; THIS FILE HAS BEEN STRIPPED TO LEAVE ONLY THE SOURCE THAT PRODUCES ; THE CODE THAT MATCHES THE SHEPARDSON ASSEMBLER/EDITOR CARTRIDGE. ; ALL DEBUG, APPLE, & MATHPACK CODE HAS BEEN REMOVED. ; MIKE LORENZEN ; ; .TITLE 'SHEPARDSON ATARI EDITOR - 2/3/81- TANDEM JUN 11,81 (ML)' ; .LIST X ; 5.6 12-10-79 ; PROGRAMMER KATHY O'BRIEN ; 8 BIT ASSEMBLER ; ;****************************************************************************** ; (C) COPYRIGHT 1978 SHEPARDSON MICROSYSTEMS, INC. ;****************************************************************************** ; DEFRA MACRO LABEL .BYTE $C0+(LABEL-*) ENDM ; CVAFP = $D800 AFP = $D800 FASC = $D8E6 IFP = $D9AA FPI = $D9D2 INTLBF = $DA51 ILSHFT = $DA5A SKPBLK = $DBA1 TSTNUM = $DBAF ; ; ATARI VERSION ZICB = $20 ; ZERO PAGE IOCB ZPG1 = $80 ZPG2 = $E6 ZPG3 = $FB MISCRAM = $500 RAM2 = $480 CIO = $E456 SETBVB = $E45C XITVBV = $E462 IOCBORG = $340 DCBORG = $300 ROM = $A000 ZFP = $D2 CR = $9B TC = $7F BELL = $FD LMADR = $2E7 HMADR = $2E5 FPORG = $D800 BRKVEC = $206 BRKBYT = $11 WARMFLG = $08 DOSLOC = $0A BYELOC = $E471 DSPFLG = $2FE ; ATARI DISPLAY FLAG SKCTL = $D20F ; AUDIO CRTGI = $BFFC-3 ; CART END ADDR APHM = $E ; APPLICATION HI MEM ; .PAGE 'ZERO PAGE' ; ; RAM TABLE POINTERS - MUST BE IN ZERO PAGE ; *=ZPG1 LOMEM ; LOW MEMORY POINTER OUTBUFF *=*+2 ; SYNTAX OUTPUT BUFFER EXBUFF ; EXECUTION BUFFER OBJBUF *=*+2 ; OBJECT BUFFER OBJEND ; END JOB, SET BUFFER TXTTAB *=*+2 ; TEXT TABLE POINTER STMCUR *=*+2 ; CURRENT PGM PTR TXTEND ; END OF TEXT SMBLTP *=*+2 ; SYMBOL TABLE POINTER SMBLEND *=*+2 ; SYMBOL TABLE END SMBLD ; SYMBOL TABLE DUMMY END TITLEP *=*+2 ; TITLE BUFFER POINTER TITLEND ; END OF TITLE BUFFER PAGEP *=*+2 ; PAGE BUFFER POINTER PAGEND ; END OF PAGE BUFFER MEMTOP *=*+2 ; TOP OF USED MEMORY ; ; HIMEM = HMADR ; HIGHEST AVAIABLE MEMORY ADDR (+1) .PAGE ; ; MISC ZERO PAGE RAM ; USED FOR FREQUENCY USED VALUES ; TO DECREASE ROM SIZE AND INCREASE ; EXECUTION SPEED. ALSO USED FOR VARIOUS ; INDIRECT ADDRESS POINTERS. ; COX *=*+1 ; CURRENT OUTPUT INDEX PTBUFF ; PAGE/TITLE BUFFER PTR MSGADR SRCADR *=*+2 ; SEARCH ADR CSADR ; CHANGE START ADDR SVESA *=*+2 ; SAVE EXPAND START ADR LEADR ; LIST END ADDR CPC *=*+2 ; CUR SYNTAX PGM COUNTER OBJDEX ; OBJECT BUFFER INDEX AQ1FLG ; ALL QUERRY 1ST FLAG MAXCIX *=*+1 ; MAX SYNTAX CIX DSADR ; DISPLAY START ADDR TSLNUM *=*+2 ;TEST LINE NO LSADR ; LIST START ADDR MVLNG *=*+2 ; MOVE LENGTH MVFEA ; MOVE FROM END ADDR ECSIZE *=*+2 ; MOVE SIZE STR1LNG ; STRING 1 LENGTH STKLVL *=*+1 ; SYNTAX STACK LEVEL WORDFLG ;WORD/DBYTE FLAG OLBCNT ; # BYTES OF OBJECT PER LINE ERRNUM ; SAVED ERROR # LINLNG ; LINE LENGTH SRCCNT ; # BYTES TO SEARCH SRCSKP *=*+1 ; SEARCH SKP FACTOR COPTR ; CURRENT ORG POINTER RTNADR ; RETURN ADDR FROM STEP CURLN ; CURLN FOR AUTO DEADR ; DISPLAY END ADDR LELNUM *=*+2 ; LIST END LINE # ; NEXT SEVEN BYTES MUST STAY TOGETHER LOMFLG *=*+1 ; LOW MEM VALID FLAG PASSFLG *=*+1 ; PASS FLAF FOR ASM AUTOFLG *=*+1 ; AUTO LINE # FLAG MODEFLG *=*+1 ; MODEFLAG ERRDEX *=*+1 ; ERROR BUFFER INDEX ENTDTD *=*+1 ; ENTER DEVICE TB LISTDTD *=*+1 ; LIST DEIVCE TBL LNINCR ; INCR FOR AUTO UPC *=*+2 ; USER P.C. ; LOCCNT *=*+2 ; LOCATION COUNTER ; NULFLG ; USED AS TEMP IN STRING SYNTAX ZT1 *=*+1 ; LOCAL TEMPS ; ; ; MISC PRINT FLAG ; *=ZPG2 ; DOUBLE USE FR2 MVFA *=*+2 ; MOVE FROM ADR MVTA *=*+2 ; MOVE TO ADR *=ZPG3 ; ;******** POISON - DO NOT USE ******** DEGFLG RADFLG *=*+1 ; SVCIX ; SAVE CIX FOR IF PRCNT *=*+1 ;# CHARS TO PRINT OUTCNT ; # OF BYTES MOVED BLKCNT *=*+1 ; # OF BLANKS TO PRINT TOBJDEX *=*+1 ; TEMPORARY OBJECT INDEX SVLENG *=*+1 ; SAVED STRING LENGTH FOR IF .PAGE *=ZFP-2 STOP ; SAVE TRIAL OP TABCNT ;INDEX TO WHICH TAB PTDEX ; INDEX FOR TITLE/PAGE BUFFER TPCIX ; CIX FOR PRINUM TVSCIX ; SAVE CIX FOR TVAT TSCOX *=*+1 ; TSCOW LENGTH BYTE PTR RESBYT ; RESOLVED BYTE LTYPFLG STRDEL STENUM *=*+1 ; SEARCH TABLE ENTRY NUMBER DISFLG ; DISASM CONTROL FLAG LINDEX ; LINE INDEX STMSTRT *=*+1 ; STMT START CIX REPFLG ; REPLACE FIND FLAG OBJDTD *=*+1 ;OBJECT DEVICE # .PAGE 'FLOATING POINT WORK AREA' ; ; FLOATING POINT WORK AREA ; *=ZFP+2 FPREC = 6 FMPREC = FPREC-1 ; LENGTH OF FLOATING POINT MANTISSA ; BININT ; FP REGO FR0 *=*+1 ; FP REG0 FR0M *=*+FPREC-1 ; FP REG0MANT FR0EX = FR0+2 FRE *=*+FPREC ; FP REG0 EXP FR1 *=*+1 ; FP REG 1 FR1M *=*+FPREC-1 ; FP REG1 MANT FR2 *=*+FPREC ; FP REG 2 FRX *=*+1 ; FP SPARE ; ; RMB FOR ASCII TO FLOATING POINT CONVERSION ; EEXP *=*+1 ; VALUE OF E FRSIGN NSIGN *=*+1 ; SIGN OF # SQRCNT PLYCNT ESIGN *=*+1 ; SIGN OF EXPONENT SGNFLG FCHRFLG *=*+1 ; 1ST CHAR FLAG XFMFLG DIGRT *=*+1 ; # OF DIGITS RIGHT OF DECIMAL ; ; INPUT BUFFER ; CIX *=*+1 ; CURRENT INPUT INDEX INBUFF *=*+2 ; LINE INPUT BUFFER ; ; ; ZTEMP1 *=*+2 ; LOW LEVEL ZERO PAGE TEMPS ZTEMP4 *=*+2 ; X ZTEMP3 *=*+2 ; X .PAGE 'MISC NON-ZERO PAGE RAM' ; ; MISC NON-ZERO PAGE RAM ; USED FOR VALUES NOT ACCESSED FREQUENTLY *=MISCRAM SSTACK =* ; SYNTAX STACK SIX *=*+1 ; INPUT INDEX SOX *=*+1 ; OUTPUT INDEX SPC *=*+2 ; PGM COUNTER *=SSTACK+126 LBPR1 *=*+1 ; LBUFF PREFIX 1 LBPR2 *=*+1 ; BLUFF PREFIX 2 LBUFF *=*+128 ; LINE BUFFER ; .PAGE ; ; RAM ; *=RAM2 ; ; USER-ACCESSIBLE FLAGS ; LINESPERPAGE *=*+1 ; SET TO DEFAULT BY COLDSTART FFOK *=*+1 ; DEFAULT: FF NOT OK ; FNBUFF *=*+20 ; FILE NAME BUFFER ERRCNT *=*+1 ; HOW MANY, DURING ASM TAB1 *=*+1 ; TAB 1 FOR ASSM LISTING ILEN ; INSTRUCTION LENGTH TAB2 ; TAB 2 FOR ASM LISTING STRDEX *=*+1 ; INDEX INTO STRING1 PMASK ; PRINT MASK TAB3 *=*+1 ; TAB 3 FOR ASM LISTING LNCNT *=*+1 ; LINE COUNT FOR ASM + DISASM EOFFLG *=*+1 ; EOF FLAG IOCMD *=*+1 ; I/O COMMAND IODVC *=*+1 ; I/O DEVICE ; ERRBUF *=*+3 ; ERROR BUFFER ; LMSAV *=*+2 ; LOMEM SAVE AREA ; TEMPRL ; TEMPORARY RECORD LENGTH FOR POINT UREG *=*+5 ; USER REGISTER URA = UREG ; URX = UREG+1 URY = UREG+2 URP = UREG+3 URS = UREG+4 ; ASM FIELDS ; STR2LNG ; STRING 2 LENGTH IDISPL *=*+1 ; DISPL TO START OF INSTRUCTION ADISPL *=*+1 ; DISPL TO ADDR CDISPL *=*+1 ; DISPL TO COMMENT OPTFLG *=*+1 ; OPTION FLAG POX *=*+1 ; PRINT OUTPUT INDEX ZT2 *=*+1 .PAGE 'IOCB AREA' *=IOCBORG ; ; IOCB - I/O CONTROL BLOCK ; THERE ARE 8 I/O CONTROL BLOCKS ; 1 IOCB IS REQUIRED FOR EACH ; CURRENTLY OPEN DEVICE OF FILE. ; IOCB ICHID *=*+1 ; DEVICE HANDLER ID ICDNO *=*+1 ; DEVICE NUMBER ICCOM *=*+1 ; I/O COMMAND ICSTA *=*+1 ; I/O STATUS ICBAL *=*+1 ICBAH *=*+1 ; BUFFER ADR (H,L) ICPUT *=*+2 ; PUT ADDR ICBLL *=*+1 ICBLH *=*+1 ; BUFFER LENGTH (H,L) ICAUX1 *=*+1 ; AUXILLIARY 1 ICAUX2 *=*+1 ; AUXILLIARY 2 ICAUX3 *=*+1 ; AUXILLARY 3 ICAUX4 *=*+1 ; AUXILLARY 4 ICAUX5 *=*+1 ; AUX 5 *=*+1 ; SPARE ICLEN = *-IOCB ; *=*+ICLEN*7 ; SPACE FOR 7 MORE IOCBS ; ; ICCOM VALUE EQUATES ; ICOIN = $01 ; OPEN INPUT ICOOUT = $02 ; OPEN OUTPUT ICOIO = $03 ; OPEN UN/OUT ICGBR = $04 ; GET BINARY RECORD ICGTR = $05 ; GET TEXT RECORDS ICGBC = $06 ; GET BINARY CHAR ICGTC = $07 ; GET TEXT CHAR ICPBR = $08 ; PUT BINARY RECORD ICPTR = $09 ; PUT TEXT RECORD ICPBC = $0A ; PUT BINARY CHAR ICPTC = $0B ; PUT TEXT CHAR ICCLOSE = $0C ; CLOSE FILE ICSTAT = $0D ; GET STATUS ICDDC = $0E ; DEVICE DEPENDENT ICMAX = $0E ; MAX VALUE ICFREE = $FF ; IOCB FREE INDICATOR ; ; ICSTA VALUE EQUATES ; ICSOK = $01 ; STATUS GOOD, NO ERRORS ICSTR = $02 ; TRUNCATED RECORD ICSEOF = $03 ; END OF FILE ICSBRK = $80 ; BREAK KEY ABORT ICSDNR = $81 ; DEVICE NOT READY ICSNED = $82 ; NON-EXISTENT DEVICE ICSDER = $83 ; DATA ERROR ICSIVC = $84 ; INVALID COMMAND ICSNOP = $85 ; DEVICE/FILE NOT OPEN ICSIVN = $86 ; INVALID IOCB NUMBER ICSWPE = $87 ; WRITE PROTECTION PTCMD = $25 ; POINT COMMAND NTCMD = $26 ; NOTE COMMAND .PAGE ; ; MISC EQUATES ; KWSTRT = $08 ; 1ST KW TOKEN -1 PEJECT = $0C ; PAGE EJECT CHAR DELIM = $3C ; DELIMITER FOR DEBUG LCHK1 = $FF ; LOAD CHECK CHAR 1 LCHK2 = $FF ; LOAD CHECK CHAR 2 ; ; MODEFLAG EMODE = 0 ; DEIT MODE INDICATOR DMODE = 1 ; DEBUG MODE AMODE = -1 ; ASM MODE MAMODE = $80 ; MINI-ASM MODE ; AUTOFLAG AUTON = $80 ; AUTOLINE # ON AUTOFF = 0 ; AUTO LINE # OFF ; ; LIST TYPE FLAG LNUMON = 0 ; LIST LINE NUMBERS LNUMOFF = $80 ; DO NOT LIST LINE NUMBERS ; ; PASS FLAG/LABEL DEFINE BYTE ; PASS1 = $80 ; THIS IS PASS 1 PASS2 = $40 ; THIS IS PASS 2 NZ = 1 ; NOT ZERO PAGE EQULBL = 2 ; EQUATE TYPE LABEL ; ; OPTION FLAG ; OLIST = $80 ; NO GENERATE LISTING OOBJ = $40 ; NO GENERATE OBJECT OERR = $20 ; NO GENERATE ERROR MESSAGE OPAGE = $01 ; NO PAGE AFTER 56 LINES ; ; DEVICE EQUATES ; SCRDV = 0 ; SCREEN LISDV = 1 ; LIST OBJDV = 2 ; OBJECT LOADDV = 3 ; LOAD TXTDV = 3 ; TEXT SOURCE ; ; AQ1FLG - (ALL QUERRY,1) ; SETA = 1 ; FIND (REPLACE) ALL OCCURENCES SETQ = -1 ; QUERRY USED ON EACH OCCURENCE SET1 = 0 ; FIND (REPLACE) 1ST OCCURENCE ; ; REPFLG - REPLACE/FIND ; REPON = $80 ; DO REPLACE FINDON = 0 ; DO FIND ; ; REPLACE QUERRY RESPONCE ; CDO = $59 ; DO REPLACE CNODO = CR ; DON'T DO REPLACE ; ; MOVE TYPE FLAG/DISASM FLAG ; ADDRON = 0 ; ADDR TYPE FILEON = $80 ; FILE TYPE CNTON = $80 ; CONTROL BY COUNT ; ; WORDFLG - WORD/DBYTE ; WORDON = $0 DBYTEON = $80 ; ; OLBCNT ; TWOBYTE = 2 ONEBYTE = 1 THRBYTE = 3 ; PLST = 12 ; START OF PRINT OF EMPTY LINE .PAGE ; ; SPECIAL TOKEN EQU ; THEX2 = $01 ; 2 BYTE HEX # OR ADDR TSTR = $02 ; STRING TSOE = $03 ; START OF EXPRESSION TEOE = $04 ; END OF EXPRESSION TLBL = $01 ; LABEL TNLBL = $00 ; NO LABEL TCOMM = $00 ; COMMENT CODE TDIR = $01 ; DIRECTIVE TIMP = $02 ; IMPLIED ADDR INST. TREL = $03 ; RELATIVE ADDR INST. TMISC = $04 ; MISC INST. TMULTI = $05 ; MULTI ADDR INST. TMACRO = $06 ; MACRO ; ; ADDRESSING MODES ; TINDX = $00 TINDY = $01 TIMM = $02 TACU = $03 TZPG = $04 TZPGY = $05 TZPGX = $06 TABS = $07 TABSY = $08 TABSX = $09 .PAGE ; ; ERROR MESSAGE NUMBERS ; MEMFULL = 1 ; MEMORY FULL - ABORT IF IN ASM ERNLN = 2 ; 1ST LINE IN DELETE RANGE NOT FOUND ERMSYN = 3 ; ERROR IN MINI ASSM ADDR ERLOAD = 4 ; FILE NOT A LOADABLE FILE ERNDEF = 5 ; UNDIFINED REFERENCE ERASYN = 6 ; ASSEMBLER SYNTAX ERROR ERDUP = 7 ; DUP LABEL EROVR = 8 ; BUFFER OVERFLOW EREQU = 9 ; EQU HAS NO LABEL ERVAL = 10 ; VALUE OF EXPRESSION > 255 ERNSTR = 11 ; NULL STRING ERADR = 12 ; INVALID ADDRESS OR ADDRESS TYPE ERPHAS = 13 ; PHASE ERROR ERUFR = 14 ; UNDEFINED FORWARD REFERENCE (*=) - ABORT ERLBIG = 15 ; LINE TOO BIG ERGARB = 16 ; INPUT TO ASSM IS GARABAGE ERLNUM = 17 ; LINE # TO BIG ERLMEM = 18 ; LOW MEM COMMAND VALID AS 1ST COMMAND ONLY ERNORG = 19 ; NO ORG GIVEN EROVFL = 20 ; OVERFLOW ON NUMBER FOR NUM OR RENUM .PAGE 'ROM START' ; ; START OF ROM CODE ; *=ROM .PAGE 'COLD START' ; ; COLD START - REINITIZES ALL MEMORY ; WIPES OUT ANY EXISTING PROGRAM COLDSTART LDA WARMFLG ; IF WARMSTART BNE WARMSTART ; THEN BR LDX #$FF ;GET STACK VALUE TXS ; SET STACK CLD ; CLEAR DECIMAL MODE JSR CLRMEM ; ; LDA #0 LDX #6 ; SET SEVERAL FLAGS TO ZERO _CLFLG STA LOMFLG,X DEX BPL _CLFLG ; STA FFOK ; USE "STX FFOK" TO CHANGE DEFAULT LDA #59 ; DEFAULT LINES PER PAGE STA LINESPERPAGE ; .PAGE 'WARM START' ; ; WARMSTART - BASIC RESTART ; DOES NOT DESTROY CURRENT PGM WARMSTART CLD ; CLEAR DECIMAL MODE .PAGE 'ESYNTAX' ; ; ESYNTAX - SYNTAX ONE LINE FOR EDITOR ; ESYN2 LDA #3 ; RESET AUDIO STA SKCTL JSR PRCR LDX #.LOW.EDMSG ; PRINT READY MESSAGE LDY #.HIGH.EDMSG JSR MSGXYCR ESYNTAX LDX #$FF TXS JSR SYNINIT ; DO GENERAL SYNTAX INIT BNE ESYNTAX ; BR IF BREAK ; JSR _GETLNUM ; GET LINE # BCS ECOM ; NO #, IT'S A COMMAND JMP ETXT ; PROCESS TEXT ; ECOM JSR SKPBLK ; SKIP BKANKS LDY CIX ; GET INDEX STY STMSTRT ; SAVE IN CASE OF SYNTAX ERROR ; JSR KWSRCH ; SEARCH KWTAB ; CPX #6 ; IS IT AN EDITOR COMMAND BNE _ESERR ; IF NOT, ERROR JSR COMSYN ; SYNTAX BCS _ESERR ; BR IF ERR ; ; JSR COMEXEC LDA #$80 ; SET LOMEM NOT VALID COMMAND STA LOMFLG ; X JMP ESYN2 ; ; ; EDMSG .BYTE 'EDI',$80+'T' .PAGE 'DSYNTAX' ; ; DSYNTAX - SYNTAX ONE LINE FOR DEBUG ; DSYN2 JSR PRCR LDX #.LOW.BUGMSG ; PUT OUT READY LDY #.HIGH.BUGMSG JSR MSGXYCR DSYNTAX JSR SYNINIT ; DO SYNTAX INIT BNE DSYNTAX ; LDY CIX ; GET INPUT LINE INDEX STY STMSTRT ; SAVE IN CASE OF SYNTAX ERROR ; JSR KWSRCH ; SEARCH FOR COMMAND ; CPX #7 ; IS IT DEBUG COMMAND BNE _DSERR ; IF NOT, ERROR ; JSR COMSYN ; SYNTAX COMMAND BCS _DSERR ; ; EXECUTE COMMAND ; JSR COMEXEC JMP DSYN2 ; ; ; BUGMSG .BYTE 'DEBU',$80+'G' .PAGE ; ; COMSYN - COMMON SYNTAXING FOR EDITOR AND DEBUG ; ; COMSYN JSR SKPBLK ; ; GET SYNTAX TABLE ADDR ; LDA STENUM ; GET EDITOR COMMAND # ASLA ; MULT BY 2 TAY ; PUT IN Y AS INDEX PHA ; SAVE LDA ESTBL-CSEDIT-CSEDIT,Y ; GET SYNTAX TABLE ADDR LOW LDX ESTBL-CSEDIT-CSEDIT+1,Y ; ADDR HI ; JSR _SYNENT ; DO BASIC SYNTAX PLA ; GET INDEX RTS _ESERR JSR WHAT ; PRINT WHAT? JMP ESYN2 _DSERR JSR WHAT ; PRINT WHAT? JMP DSYN2 ; ; ; ; ; WHAT - PRINT WHAT? MESSAGE ; WHAT LDA #BELL ; PUT OUT BELL JSR PRCHAR LDX #.LOW.WHTMSG LDY #.HIGH.WHTMSG JMP MSGXYCR ; ; ; WHTMSG .BYTE 'WHAT',$80+'?' .PAGE ; ; COMEXEC - EXECUTE COMMAND FOR DEBUG AND EDITOR ; ; ON ENTRY A - CONTAINS COMMAND # * 2 COMEXEC ; ; GET EXECUTION ROUTINE ADDR ; JSR _EDUM ; ; RETURN HERE FROM COMMAND EXC RTS ; _EDUM TAY ; GET INDEX LDA EXTBL-CSEDIT-CSEDIT+1,Y ; X PHA ; X LDA EXTBL-CSEDIT-CSEDIT,Y ; GO TO ROUTINE PHA ; X LDY #0 ; GET ZERO STY COX ; RESET OUTPUT INDEX RTS .PAGE 'ASSEMBLER SYNTAX' ; ; ASYNTAX - SYNTAX LINE FOR ASM ; ; ON EXIT CARRY SET - IF SYNTAX ERROR ; CARRY CLEAR - IF NOT ; ASYNTAX ; ; PROCESS POSSIBLE LABEL ; LDY CIX ; GET 1ST CHAR LDA (INBUFF),Y ; X CMP #'; ; IS IT COMMENT CARD BEQ _COMMENT ; BR IF YES CMP #$20 ; IS IT BLANK BEQ _NOLBL ; IF YES, NO LABEL ; JSR LBLSRCH ; GO SEARCH FOR LABEL BCS _ASERR ; IF INVALID BRANCH ; LDY #2 ; GET DEFINE BYTE LDA (SRCADR),Y ; X PHA ; SAVE DEFINE BYTE BMI _DLBL1 ; IF PASS 1 DEFINE BIT ON, BR ; LDA LOCCNT+1 ; SET ADDR IN LABEL TABLE DEY ; X STA (SRCADR),Y ; X LDA LOCCNT ; X DEY ; X STA (SRCADR),Y ; X JMP _DLBL3 _DLBL1 ; ; TEST FOR PHASE ERROR ; AND #EQULBL ;IS THIS AN EQU ? BNE _DLBL3 ;IF YES DO NOT CHECK PHASE LDA LOCCNT+1 ; CURRENT LOCATION COUNTER DEY ; MUST = TABLE ADDR CMP (SRCADR),Y ; X BNE _PHERR ; X LDA LOCCNT ; X DEY ; X CMP (SRCADR),Y ; X BEQ _DLBL3 ; X ; _PHERR LDA #ERPHAS ; PHASE ERROR JSR ERROR ; _DLBL3 PLA ; GET DEFINE BYTE PHA ; SAVE DEFINE BYTE ASLA ; SHIFT BPL _DLBL2 ; IF PASS 2 DEFINE BIT OFF, THEN BR LDA #ERDUP ; PUT ERROR # IN BUFFER JSR ERROR ; X _DLBL2 PLA ; GET DEFINE BYTE ORA PASSFLG ; OR IN PASSFLG LDY #2 STA (SRCADR),Y ; SAVE IN LABEL TABLE ; ; PUT LABEL CODE & ADDR IN OUTPUT LINE ; LDA #TLBL ; SET LABEL CODE IN OUTPUT JSR _SETCODE ; X LDA SRCADR ; PUT LABEL ADDR IN OUTPUT LDX SRCADR+1 JSR _SETC2 JMP _ASYN1 ; ; ; ; ; _ASERR LDA #ERASYN JSR ERROR _COMMENT LDY #3 ; SET LABEL CODE LDA #TCOMM ; IN OUTPUT BUFFER STA (OUTBUFF),Y ; X SEC RTS _NOLBL LDA #TNLBL ; GET NO LABEL CODE JSR _SETCODE ; PUT IN OUTPUT INC COX ; INCR TO OP CODE DISPL INC COX ; X .PAGE ; ; SYNTAX OPERATOR ; _ASYN1 JSR SKPBLK ; SKIP BLANKS LDY CIX LDA (INBUFF),Y CMP #CR ; IS THIS BLANK LINE OR LABEL ONLY? BEQ _COMMENT LDA CIX ; SET DISPL TO INST OP STA IDISPL ; X ; JSR KWSRCH ; FIND OP BCS _ASERR ; ERROR IF NOT FOUND CPX #6 ; IS IT ASSM COMMAND? BCS _ASERR ; IF NOT ERROR ; TXA JSR _SETCODE ; SET TYPE IN OUTPUT LDA STENUM ; GO SEARSH TABLE ENTRY # JSR _SETCODE ; PUT IN OUTPUT CPX #TDIR ; IS IT DIRECTIVE? BEQ _ASYN3 ; ; GET TRIAL OP CODE ; _ASYN2 TAY ; GET TRIAL OP LDA TOPTBL-CSMNEM,Y ; X JSR _SETCODE ; SET I OUTPUT ; _ASYN3 JSR SKPBLK ; SET DIAPL ADDR LDY CIX ; X STY ADISPL ; X ; ; PROCESS ADDR ; TXA ASLA ; GET ROUTINE ADDR TAY ; BY COMMAND TYPE LDA ASTBL+1,Y ; X PHA LDA ASTBL,Y ; X PHA ; X RTS ; GO TO ROUTINE .PAGE ; ; ; ASMULT - SYNTAX MULTI ADDR TYPE INSTR ; ASMULT LDA #.LOW._SMULT ; GET SYNTAX TABLE ADDR LDX #.HIGH._SMULT ; ; ; ; OPSYN JSR _SYNENT ; DO BASIC SYNTAX BCS _ASERR ; ; ; ; ; ASIMP - SYNTAX IMPLIED INSTRUCTION ; ASIMP JSR SKPBLK ;SKIP BLANKS LDY CIX ; SET DISPL TO COMMENT STY CDISPL ; X LDA #CEOL ; SET END OF LINE IN OUTPUT JSR _SETCODE ; X RTS ; ; ; ; ASDIR - SYNTAX ASM DIRECTIVE ; ; ON ENTRY SEARCH TABLE ENTRY # IN A ; ASDIR LDA STENUM ; GET WHICH DIRECTIVE ASLA ; SET SYNTAX TABLE TAY ; ADDR IN LDA ADSTBL-CSDIR-CSDIR,Y ; PROGRAM COUNTER LDX ADSTBL-CSDIR-CSDIR+1,Y BNE OPSYN ; DO SYNTAX ; ; ; ; ; ; ASREL - SYNTAX RELATIVE INSTRUCTION ; ASREL LDA #.LOW._SREL ; SET SYNTAX ROUTINE ADDR LDX #.HIGH._SREL ; BNE OPSYN ; DO SYNTAX ; ; ; ; ; ASMISC - SYNTAX MISCELLANEOUS INSTRUCTION ; ASMISC LDA STENUM ; GET SEARCH TABLE ENTRY # CMP #CJSR ; IS IT JSR BEQ ASREL ; IF YES, SYNTAX LIKE BR ; LDA #.LOW._SJMP ; GET SYNTAX TABLE ADDR LDX #.HIGH._SJMP ; BNE OPSYN ; DO SYNTAX .PAGE ; ETXT LDY CIX ; GET INDEX LDA (INBUFF),Y ; GET 1ST CHAR CMP #CR ; IS IT CR BEQ _DEL ; IF YES DELETE LINES ; ; LDX AUTOFLG ; ARE WE IN AUTO? BEQ _ETXT4 ; IF NOT BR ; INY ; ELSE GET NEXT CHAR LDA (INBUFF),Y ; X CMP #CR ; IS IT CR BNE _ETXT4 ; IF NOT BR ; LDA #AUTOFF ; ELSE TURN OFF AUTO STA AUTOFLG ; X BEQ _ETXT3 ; AND THUS GET TO 'ESYNTAX' ; _ETXT4 JSR _SETCODE ; SET DUMMY FOR LENGTH ; ; MOVE INPUT TO OUTBUFF ; _ETXT2 LDY CIX ; GET INDEX LDA (INBUFF),Y ; GET INPUT CHAR JSR _SETCODE ; PUT IN OUTBUFF INC CIX ; INCR INDEX CMP #CR ; WAS CHAR CR? BNE _ETXT2 ; IF NOT, GET NEXT CHAR ; _SYN4 LDY #2 ; SET LINE LENGTH LDA COX ; INTO STMT STA (OUTBUFF),Y ; ; _SYN5 JSR GETSTMT ;GO GET STMT LDA #0 BCS _SYN6 ; IF LINE # DOES NOT EXIT, BR ; _SYN5A JSR GETLL ;GO GET LINE LENGTH _SYN6 SEC SBC COX ;ACU=LENGTH(OLD-NEW) BEQ _SYNIN ; BR NEW=OLD BCS _SYNCON ;BR OLD>NEW ; ;OLD1 ; JSR _GETADR ; CODE=1 (EXTERNAL SUBROUTINE) BCC _NEXT ; BR IF SUB REPORTS SUCCESS BCS GO_FAIL ; _TSTSUC CMP #5 ; TEST CODE = 5 BCC _POP ; CODE = (2,3,OR 4) POP UP TO NEXT STACK LEVEL ; JSR _TERMTST ; CODE>5 GO TEST TERMINAL BCC _NEXT ; BR IF SUCCESS GO_FAIL = * JMP _FAIL ; ELSE GO TO FAIL CODE ; _ERNTV SEC ; RELATIVE NON TERMINAL SBC #$C1 BCS _ERN1 ; BR IF RESULT PLUS DEX ; X = MINUS ONE _ERN1 CLC ADC CPC ; RESULT PLUS CPC PHA ; IS NEW CPC-1 TXA ADC CPC+1 PHA ; SAVE NEW PC HIGH JMP _PUSH ; GO PUSH _GETADR = * ; GET DOUBLE BYTE ADR (-1) JSR _NXSC ; GET NEXT CODE PHA ; SAVE ON STACK JSR _NXSC ; GET NEXT CODE PHA ; SAVE ON STACK BCC _PUSH ; BR IF CODE =0 PLA ; EXCHANGE TOP TAY ; 2 ENTRIES ON PLA ; CPU STACK TAX TYA PHA TXA PHA RTS ; ELSE GOTO EXTERNAL SRT VIA RTS _TBIG LDA #ERLBIG JSR ERROR PLA ; CLEAR CPU STACK PLA SEC RTS ; ; PUSH - PUSH TO NEXT STACK LEVEL ; _PUSH = * LDX STKLVL ; GET STACK LEVEL INX ; PLUS 4 INX INX INX BMI _TBIG ; IF MINUS, STACK OVERFLOW STX STKLVL ; SAVE NEW STACK LEVEL ; LDA CIX ; CIX TO STA SIX,X ; STACK IX LDA COX ; COX TO STA SOX,X ; STACK OX LDA CPC ; CPC TO STA SPC,X ; STACK CPC LDA CPC+1 STA SPC+1,X ; PLA ; MOVE STACKED STA CPC+1 ; PC TO CPC PLA STA CPC GO_NEXT = * JMP _NEXT ; GO FOR NEXT ; ; POP - LOAD CPC FORM STACK PC ; AND DECREMENT TO PREV STACK LEVEL ; _POP = * LDX STKLVL ; GET STACK LEVEL BNE _POP1 ; BR NOT TOP OF STACK ; RTS ; TO SYNTAX CALLER ; _POP1 LDA SPC,X ; MOVE STACK PC STA CPC ; TO CURRENT PC LDA SPC+1,X STA CPC+1 ; DEX ; X=X-4 DEX DEX DEX STX STKLVL ; BCC GO_NEXT ; NOT FAILING ; ; FAIL - TERMINAL FAILED ; LOOK FOR ALTERNATIVE (OR) OR ; A RETURN INDICATOR ; _FAIL = * JSR _NXSC ; GET NEXT CODE ; BMI _FAIL ; BR IF RNTV CMP #8 ; IS IT SETCODE? BEQ _INC1 ; IF YES, INCR OVER CODE ; ; CMP #2 ; TEST CODE =2 BCS _TSTOR ; BR IF POSSIBLE OR ; JSR _INCCPC ; CODE = 0 OR 1 _INC1 JSR _INCCPC ; INC PC BY TWO BNE _FAIL ; AND CONTINUE FAIL PROCESS ; _TSTOR CMP #3 ; TEST CODE=3 BEQ _POP ; BR CODE =3 (RETURN) BCS _FAIL ; CODE>3 (RNTV) CONTINUE ; LDA CIX ; IF THIS CIX CMP MAXCIX ; IS A NEW MAX BCC _SCIX STA MAXCIX ; THEN SET NEW MAX _SCIX LDX STKLVL ; CODE=2 (OR) LDA SIX,X ; MOVE STACK INDEXES STA CIX ; TO CURRENT INDEXES LDA SOX,X STA COX JMP _NEXT ; TRY FOR SUCCESS HERE .PAGE ; ; INCCPC - INC CPC BY ONE ; _INCCPC = * INC CPC BNE _ICPCR INC CPC+1 _ICPCR RTS ; ; .PAGE ; ; _NXSC - GET NEXT SYNTAX CODE ; _NXSC JSR _INCCPC ; INC PC LDX #0 LDA (CPC,X) ; GET NEXT CODE RTS ; RETURN .PAGE ; ; TERMTST - TEST A TERMINAL CODE ; _TERMTST CMP #_SCODE ; TEST CODE = SET CODE BEQ _SET ; IF YES, GO SET CODE IN OUTPUT BCS _SRCONT ; IF >, THEN MUST BE OPERATOR ; IF <, THEN DO EXPRESSION PLA ; POP RTN ADR PLA LDA #.LOW._EXP-1 ; PUSH EXP ADR PHA ; FOR SPECIAL LDA #.HIGH._EXP ; EXP ANTV CALL PHA JMP _PUSH ; GO PUSH ; .PAGE ; ; _SETC2 -- SETCODE FROM BOTH A & X REGS ; _SETC2 JSR _SETCODE TXA ; FALL THRU TO _SETCODE ; ; ; SETCODE-SET CODE IN ACV AT COX AND INC COX ; _SETCODE LDY COX ;GET COX STA (OUTBUFF),Y ;SET CHAR INC COX ;INC COX BEQ _SCOVF ;BR IF NOT ZERO CLC RTS ;DONE _SCOVF LDA #EROVR JSR ERROR RTS .PAGE ; ; TSTALPH - TEST CIX FOR ALPHA ; _TSTALPH TSTALPH LDY CIX LDA (INBUFF),Y CMP #'A-1 BCC _TAFAIL CMP #$5B RTS ; _TAFAIL SEC RTS .PAGE ; ; _SRCONT - SEARCH FOR OPERATOR ; _SRCONT PHA ; SAVE SYNTAX TABLE CODE JSR KWSRCH ; SEARCH KEYWORD TABLE PLA ; GET TOKEN BCS _SRFAIL ; IF ERROR, BR ; ; CMP STENUM ; COMP TO SEARCH RESULT BNE _SRFAIL ; IF NOT = THEN FAIL BEQ _LOC1 ; ELSE PUT IN BUFFER ; _SRFAIL SEC RTS .PAGE ; ; SET - EXTERNAL CODE TO SET A TOKEN INTO LINE ; _SET JSR _INCCPC ; INC PC TO CODE LDY #0 LDA (CPC),Y ; GET CODE ; JMP _SETCODE ; CODE TO BUFFER .PAGE ; ; LBLREF - EXTERNAL SUBROUTINE FOR LABEL REFERENCE ; _LBLREF JSR LBLSRCH ; GO SEARCH FOR LABEL BCS _SRFAIL ; BR IF FAIL ; LDY #2 LDA (SRCADR),Y ; GET DEFINE BYTE FOR LABEL BMI _LBLR1 ; IF PASS 1 DEF BIT ON, DONE ; PHA LDA #ERNDEF ; GET NOT DEFINED ERROR JSR ERROR PLA _LBLR1 LDX #THEX2 ; GET HEX # CODE AND PASSFLG ; HAS LABEL BEEN DEFINED THIS PASS? BNE _LBLR3 ; IF YES, BR ; _LBLR2 LDY #2 ;GET DEFINE FLAG LDA (SRCADR),Y ;X ORA #NZ ;OR IN ABSOLUTE FLAG STA (SRCADR),Y ;SAVE IT IN TABLE LDX #THEX2+$80 ; GET UNSOLVED REF CODE _LBLR3 TXA ; PUT # CODE IN A JSR _SETCODE ; SET IN OUTPUT LDY #1 LDA (SRCADR),Y ; VALUE OF LABEL...HIGH DEY TAX LDA (SRCADR),Y ; & LOW JMP _SETC2 ; TO OUTPUT .PAGE ; ; GCHAR - EXTERNAL SUBROUTINE TO GET A SINGLE CHAR ; ; _GCHAR DEC COX ; BACK UP OVER QUOTE ; JSR GETIN ; GET NEXT INPUT CHAR TAX ; INPUT CHAR TO X LDA #THEX2 ; "2 BYTE HEX" -- CODE JSR _SETC2 ; BOTH TO OUTPUT ; LDA #0 ; SET NUMBER HIGH BEQ _LOC1 ; UNCONDITIONAL BR ; ; ; ; ; LOC - EXTERNAL SUBROUTINE TO PROCESS LOCATION COUNTER ; _LOC JSR SKPBLK DEC COX ; REMOVE * FROM OUTPUT LDA #THEX2 ; PUT HEX # CODE IN PUTPUT LDX LOCCNT JSR _SETC2 ; CODE && LSB TO OUTPUT LDA LOCCNT+1 ; X _LOC1 JMP _SETCODE .PAGE ; ; DEC - EXTERNAL SUBROUTINE TO CHECK FOR DECIMAL # ; _DEC JSR SKPBLK LDA CIX STA TVSCIX JSR AFP ; GO TEST AND CONV BCS _TNC3 ; ERROR JSR FPI ; CONVERT TO INTEGER BCC _TNC1 ; BR IF NUMBER _TNC3 LDA TVSCIX STA CIX RTS ; RETURN FAIL ; _TNC1 LDA #THEX2 ; 2 BYTE HEX CODE JSR _SETCODE ; ; _STNUM LDA FR0 ; GET # LOW LDX FR0+1 ; & HIGH JMP _SETC2 .PAGE ; ; HEX - EXTERNAL SUBROUTINE TO HANDLE HEX NUMBERS ; ; HEXD - REMOVE $ FROM OUTPUT , THEN PROCESS LIKE HEX ; _HEXD DEC COX ; REMOVE $ FROM OUTPUT GETHEX _HEX JSR SKPBLK ;SKIP BLANKS ; ; CLEAR INTEGER ; LDA #0 STA ZTEMP4 ; CLEAR INTEGER RESULT STA ZTEMP4+1 ; X ; ; DO CONVERT ; JSR _HEXIN ; GET A HEX DIGIT IN A BCS _HFAIL ; ; ; ADD IN DIGIT ; _HEX1 CLC ; ADD DIGIT TO RESULT ADC ZTEMP4+1 ; X STA ZTEMP4+1 ; X LDA ZTEMP4 ; X ADC #0 ; X STA ZTEMP4 ; X ; ; GET NEXT DIGIT ; JSR _HEXIN ; GET NEXT DIGIT IN A BCS _HEX2 ; IF NOT A DIGIT, BR ; ; ; MULT INTEGER RESULT BY 16 ; LDX #4 ; SHIFT 2 BYTE INTEGER 4 TIMES _SHIFT JSR ILSHFT ; SHIFT 1 BIT BCS _HFAIL ; IF CARRY SET, THEN # TOO BIG ; DEX ; DEC COUNT BNE _SHIFT ; IF MORE TO DO, BR ; ; JMP _HEX1 ; REPEAT ; _HEX2 LDA #THEX2 ; PUT NUMBER CODE IN OUTPUT JSR _SETCODE ; X LDA ZTEMP4+1 ; PUT # IN OUTPUT LDX ZTEMP4 JSR _SETC2 ; BOTH BYTES DEC CIX ; BACK UP TO LAST CHAR _HFAIL RTS .PAGE ; ; HEXIN - GET A HEX DIGIT FROM INPUT BUFFER ; ; ON EXIT CARRY SET IF CHAR NOT VALID HEX ; CARRY CLEAR IF VALID ; A - DIGIT ; _HEXIN JSR GETIN ; GET INPUT CHAR SEC SBC #$30 ; SUBTRACT 30 BMI _NHEX ; IF CHAR <30, THEN NOT HEX CMP #$A ; IS RESULT < 10? BCC _HEND ; IF YES, HAVE DIGIT SBC #7 ; SUB 7 MOVE CMP #$A ; IS IT LESS THAN HEX A? BCC _NHEX ; IF CMP #$10 ; IS RESULT < 16 BCC _HEND ; IF YES, HAVE DIGIT ; _NHEX SEC ; SET RETURN FAIL _HEND RTS .PAGE ; ; STR1 - CHECK FOR STRING WITH ANY DELIMETER ; ; STR2 - CHECK FOR STRING WITH SAME DELIMETER AS 1ST STRING ; ; STR3 - CHECK FOR QUOTED STRING ; ; ; ; _FSTR - EXTERNAL SUBROUTINE TO PROCESS FILE SPEC STRING ; ; _FSTRM - PROCESS FILE SPEC STRING ENDING IN < ; _STR1 LDA #0 ; SET NULL FLAG STA NULFLG ; TO NULL NOT VALID JSR SKPBLK LDY CIX ; GET INPUT INDEX LDA (INBUFF),Y ; GET CHAR CMP #CR ; IS IT CR? BEQ _STFAIL ; IF YES RETURN FAIL ; BNE _ST6 ;UNCONDITIONAL BRANCH ; _FSTRM LDA #'< ; GET STRING DELIMETER BNE _FS ; ; ; _FSTR LDA #', ; GET COMMA AS DELIMETER _FS LDY #0 ; SET NULL NOT VALID STY NULFLG JSR _ST2 ; HANDLE STRING BCS _FSTR1 ; IF FIND EOL, FINISH STR DEC CIX ; BACK UP TO LAST NON-FILE CHAR RTS ; ; ; ; _STR2 DEC CIX ; POINT TO DELIMETER LDA #1 ; SET NULL VALID FLAG STA NULFLG BNE _ST3 ; ; ; _STR3 LDA #0 ; SET NULL FLAG TO STA NULFLG ; NULL NOT VALID LDA #'" ; GET DOUBLE QUOTES DEC COX ; REMOVE ' FROM OUTPUT ; ; ; _ST2 DEC CIX ; BACK UP 1 CHAR BEFORE STR _ST6 STA STRDEL ; GET STRING DELIMETER ; _ST3 TAX ; SAVE FOR NOW LDA #TSTR ; GET STRING CODE JSR _SETCODE ; GO PUT IN OUTPUT ; TXA LDX COX INX STX TSCOX ; GET & SAVE OUTPUT INDEX JSR _SETC2 ; & SET AS DUMMY (WITH STRDEL) _ST4 INC CIX ; POINT TO NEXT INPUT CHAR LDY CIX ; GET INDEX LDA (INBUFF),Y ; GET CHAR CMP #CR ; IS IT CR? BEQ _STFAIL ; IF YES, IT'S AN ERROR CMP STRDEL ; IS IT DELIMETER BEQ _ST5 ; IF YES, END OF STRING JSR _SETCODE BNE _ST4 ; BR UNCONDITIONALLY ; _ST5 INC CIX ; INCR OVER DELIMETER _FSTR1 CLC ; GET STR LENGTH LDA COX ; X SBC TSCOX ; X BNE _STLEN ; IF NOT NULL, SET LENGTH LDY NULFLG ; ELSE SEE IF NULL OKAY BEQ _STFAIL ; IF FLAG =0, NULL IS ERROR _STLEN LDY TSCOX ; GET INDEX TO LENGTH IN OUTPUT STA (OUTBUFF),Y ; SAVE LENGTH ; CLC RTS ; SET RETURN PASS ; ; _STFAIL SEC ; SET RETURN FAIL RTS .PAGE ; ; LBLSRCH - SEARCH FOR LABEL IN SYMBOL MAP ; ; ON EXIT CARRY SET - NOT FOUND ; CARRY CLEAR - FOUND ; LBLSRCH LDA MODEFLG ; CAN'T HAVE LABEL CMP #MAMODE ; IN MINI-ASM BEQ _TVFAIL ; X JSR SKPBLK ; SKIP BLANKS LDA CIX ; SAVE INDEX STA TVSCIX ; X ; JSR _TSTALPH ; TEST 1ST CHAR FOR ALPHA BCS _TVFAIL ; IF NOT ALPHA, THEN FAIL ; _TV1 INC CIX ; INCR TO NEXT CHAR JSR _TSTALPH ; IS IT ALPHA? BCC _TV1 ; IF YES TRY AGAIN CMP #'. BEQ _TV1 ; IF YES, TRY AGAIN JSR TSTNUM ; IS IT NUMBER BCC _TV1 ; IF YES TRY AGAIN BCS _LBL1 ; _TVFAIL SEC ; SET FAIL RTS ; ; _LBL1 LDA TVSCIX ; RESTORE CIX STA CIX ; X STY TVSCIX ; SAVE NEW CIX (END OF LBL+1) ; LBLS1 LDA SMBLTP+1 ; SEARCH SYMBOL TABLE LDY SMBLTP LDX #3 ; GET # BYTES TO SKIP JSR SEARCH ; X ; _LBL2 BCS _LNF ; BR IF NOT FOUND CPX TVSCIX ; FOUND RIGHT ONE BEQ _LF ; IF YES, DONE JSR SRCNXT ; IF NOT, SEARCH AGAAIN JMP _LBL2 ; TEST THIS RESULT ; _LNF LDA TVSCIX ; LABEL LENGTH EQU SBC CIX ; NEW CIX - OLD CIX CMP #1 ; IS LENGTH = 1? BNE _LNF1 ; IF NOT, THIS CAN'T BE LABEL A LDY CIX ; GET 1ST CHAR LDA (INBUFF),Y ; X CMP #'A ; IS IT A BEQ _TVFAIL ; IF YES, THEN NOT LABEL LDA #1 ; ELSE OKAY ; _LNF1 STA CIX ; SAVE LENGTH ; LDY #3 ; EXPAND TABLE BY 3 LDX #SMBLEND ; X JSR EXPLOW ; X ; ; LDY #2 ; CLEAR THE 3 BYTES OF LABEL ENTRY LDA #0 ; X _LNF2 STA (SVESA),Y ; X DEY ; X BPL _LNF2 ; X ; LDY CIX ; EXPAND BY LABEL LENGTH LDX #SMBLEND ; X JSR EXPLOW ; X ; ; LDY CIX ; AND DEY LDX TVSCIX ; GET DISPL TO EQU+1 DEX _TVS1 LDA LBUFF,X ; MOVE VAR TO STA (SVESA),Y DEX DEY BPL _TVS1 ; LDY CIX ;TURN ON MSB DEY ;OF LAST CHAR LDA (SVESA),Y ;IN VTVT ENTRY ORA #$80 STA (SVESA),Y ; _LF LDA TVSCIX ; SET NEW CIX STA CIX ; X ; CLC ; SET PASS RTS .PAGE 'SEARCH ROUTINES' ; ; KWSRCH - SEARCH KEYWORD TABLE ; ; ON EXIT X - COMMAND TYPE ; 1 - DIRECTIVE ; 2 - IMPLIED ; 3 - RELATIVE ; 4 - MISCELLANEOUS ; 5 - MULTI-ADDR ; 6 - EDITOR ; 7 - DEBUG ; 10 - OTHER ; ; A - ENTRY # ; ; KWPTBL .BYTE CEDIR+1,CEIMP+1,CEREL+1 .BYTE CEMISC+1,CEMULT+1 ; KWSRCH JSR SKPBLK LDX #0 ; GET SKIP LENGTH LDA #.HIGH.KWTAB ; GET KEYWORD TABLE ADDR LDY #.LOW.KWTAB ; FOR SEARCH JSR SEARCH ; SEARCH STX CIX ; SET INPUT INDEX LDX #0 ; SET COMMAND NOT FOUND BCS _KRTN ; BR IF NOT FOUND ; ; CLASSIFY AS TYPE OF COMMAND ; LDA STENUM ; GET ENTRY # RETURNED IN SEARCH CLC ; ADD 1ST KW # ADC #KWSTRT+1 ; X STA STENUM ; SAVE NEW ENTRY # CLASF INX ; TO NEXT CMD TYPE CMP KWPTBL-1,X ; DOES THIS MATCH TBL ENTRY? BCC _KRTN ; YEP CPX #5 ; NO...MORE TO DO? BNE CLASF ; YES INX CMP #CSEDIT ; IS IT AN OPTION BCC _KRTN2 ; IF YES, NOT A COMMAND CMP #CEEDIT+1 BCC _KRTN ; INX CMP #CEBUG+1 ; IS IT DEBUG COMMAND? BCC _KRTN CLC ; CLEAR FOR FOUND _KRTN2 LDX #10 ; SET OTHER _KRTN ; CLEAR FOR RETURN PASS RTS .PAGE ; ; SEARCH - SEARCH A TABLE ; TABLE FORMAT: ; GARBAGE TO SKIP (N) ; ASCII CHAR (N) ; WITH LEAST SIGNIFICANT BYTE HAVING ; MOST SIGNIFICANT BIT ON ; LAST TABLE ENTRY MUST HAVE FIRST ASCII CHAR = 0 ; ; ENTRY PARMS: ; X = SKIP LENGTH ; A,Y = TABLE ADR (HIGH LOW) ; ARGUMENT = INBUFF + CIX ; EXIT PARMS: ; CARRY = CLEAR IF FOUND ; X = FOUND AARGUMENT END CIX+1 ; SRCADR = TABLE ENTRY ADR ; STENUM = TABLE ENTRY NUMBER ; SEARCH STX SRCSKP ; SAVE SKIP FACTOR ; LDX #$FF ; SET ENTRY NUMBER STX STENUM ; TO ZERO ; _SRC1 STA SRCADR+1 ; SET SEARCH ADR STY SRCADR INC STENUM ; INC ENTRY NUMBER LDX CIX ; GET ARG DISPL LDY SRCSKP ; GET SKIP LENGTH LDA (SRCADR),Y ; GET FIRST CHAR BEQ _SRCNF ; BR IF EOT ; _SRC2 LDA LBUFF,X ; GET INPUT CHAR AND #$7F ; TURN OFF MSB EOR (SRCADR),Y ; EX-OR WITH TABLE CHAR ASLA ; SHIFT MSB TO CARRY BEQ _SRCM1 ; CHAR IN LBUFF = CHAR IN TBL BCS _SRCME ; NO MATCH & WAS LAST CHAR IN TBL _SRCFAST INY ; NO MATCH, NOT LAST CHAR LDA (SRCADR),Y ; ...LOOP... BPL _SRCFAST ; UNTIL LAST CHAR FND _SRCME INY ; BUMP TO PAST OLD LAST CHAR ; (JOINED HERE BY LABEL TABLE RE-SEARCH) SRCNXT JSR INCSRC ; TO NEXT ENTRY BNE _SRC1 ; ALWAYS BRANCHES ; ; WE GET HERE EACH TIME LBUFF CHAR = TABLE CHAR ; _SRCM1 INY ; NEXT CHAR IN TBL INX ; NEXT IN BUFF BCC _SRC2 ; IF NOT LAST CHAR, DO IT AGAIN CLC RTS ; WE FOUND A MATCH! ; _SRCNF SEC ;INDICATE NOT FOUND RTS ; ; ; INCSRC CLC TYA ;ACV=ENTRY LENGTH ADC SRCADR ;PLUS START ADR (L) TAY ;TO Y LDA SRCADR+1 ;ETC ADC #0 RTS .PAGE 'KEYWORD NAME TABLES' ; ; KEYBOARD NAME TABLE ; KWTAB C SET KWSTRT ; ; C SET C+1 CSASM = C ; 1ST ASM CODE CSDIR = C ; 1ST DIRECTIVE CODE .BYTE '.I',$80+'F' ; C SET C+1 .BYTE '.TITL',$80+'E' ; C SET C+1 .BYTE '.PAG',$80+'E' ; C SET C+1 .BYTE '.WOR',$80+'D' ; C SET C+1 .BYTE '.BYT',$80+'E' ; C SET C+1 .BYTE '.DBYT',$80+'E' ; C SET C+1 .BYTE '.EN',$80+'D' ; C SET C+1 .BYTE '.OP',$80+'T' ; C SET C+1 .BYTE '.TA',$80+'B' ; C SET C+1 .BYTE '*',$80+'=' ; C SET C+1 .BYTE $80+'=' CEDIR = C ; LAST DIRECTIVE CODE ; C SET C+1 CSMNEM = C ; 1ST MNEMONIC CODE CSIMP = C ; 1ST IMPLIED TYPE ; KWTAB2 ; .BYTE 'BR',$80+'K' ; C SET C+1 .BYTE 'CL',$80+'C' ; C SET C+1 .BYTE 'CL',$80+'D' ; C SET C+1 .BYTE 'CL',$80+'I' ; C SET C+1 .BYTE 'CL',$80+'V' ; C SET C+1 .BYTE 'DE',$80+'X' ; C SET C+1 .BYTE 'DE',$80+'Y' ; C SET C+1 .BYTE 'IN',$80+'X' ; C SET C+1 .BYTE 'IN',$80+'Y' ; C SET C+1 .BYTE 'NO',$80+'P' ; C SET C+1 .BYTE 'PH',$80+'A' ; C SET C+1 .BYTE 'PH',$80+'P' ; C SET C+1 .BYTE 'PL',$80+'A' ; C SET C+1 .BYTE 'PL',$80+'P' ; C SET C+1 .BYTE 'RT',$80+'I' ; C SET C+1 .BYTE 'RT',$80+'S' ; C SET C+1 .BYTE 'SE',$80+'C' ; C SET C+1 .BYTE 'SE',$80+'D' ; C SET C+1 .BYTE 'SE',$80+'I' ; C SET C+1 .BYTE 'TA',$80+'X' ; C SET C+1 .BYTE 'TA',$80+'Y' ; C SET C+1 .BYTE 'TS',$80+'X' ; C SET C+1 .BYTE 'TX',$80+'A' ; C SET C+1 .BYTE 'TX',$80+'S' ; C SET C+1 .BYTE 'TY',$80+'A' CEIMP = C ; LAST IMPLIED TYPE ; C SET C+1 CSREL = C ; 1ST RELATIVE TYPE ; .BYTE 'BC',$80+'C' ; C SET C+1 .BYTE 'BC',$80+'S' ; C SET C+1 .BYTE 'BE',$80+'Q' ; C SET C+1 .BYTE 'BM',$80+'I' ; C SET C+1 .BYTE 'BN',$80+'E' ; C SET C+1 .BYTE 'BP',$80+'L' ; C SET C+1 .BYTE 'BV',$80+'C' ; C SET C+1 .BYTE 'BV',$80+'S' CEREL = C ; LAST RELATIVE TYPE ; C SET C+1 CSMISC = C ; 1ST MISC TYPE ; CJSR = C ; JSR INST. .BYTE 'JS',$80+'R' ; C SET C+1 CJMP = C ; JUMP INST. .BYTE 'JM',$80+'P' ; CEMISC = C ; LAST MISC TYPE ; C SET C+1 CSMULT = C ; 1ST MULTI ADDR ; .BYTE 'OR',$80+'A' ; C SET C+1 .BYTE 'AN',$80+'D' ; C SET C+1 .BYTE 'EO',$80+'R' ; C SET C+1 .BYTE 'AD',$80+'C' ; C SET C+1 .BYTE 'ST',$80+'A' ; C SET C+1 .BYTE 'LD',$80+'A' ; C SET C+1 .BYTE 'CM',$80+'P' ; C SET C+1 .BYTE 'SB',$80+'C' ; C SET C+1 .BYTE 'AS',$80+'L' ; C SET C+1 .BYTE 'RO',$80+'L' ; C SET C+1 .BYTE 'LS',$80+'R' ; C SET C+1 .BYTE 'RO',$80+'R' ; C SET C+1 .BYTE 'DE',$80+'C' ; C SET C+1 .BYTE 'IN',$80+'C' ; C SET C+1 .BYTE 'LD',$80+'X' ; C SET C+1 .BYTE 'LD',$80+'Y' ; C SET C+1 .BYTE 'ST',$80+'X' ; C SET C+1 .BYTE 'ST',$80+'Y' ; C SET C+1 .BYTE 'CP',$80+'X' ; C SET C+1 .BYTE 'CP',$80+'Y' ; C SET C+1 .BYTE 'BI',$80+'T' ; CEMULT = C ; LAST MULT ADDR CEMNEM = C ; LAST MNEMONIC CEASM = C ; LAST ASM CODE C SET C+1 ; 1ST OPTION CSOPT = C ; CNO = C .BYTE 'N',$80+'O' ; C SET C+1 COBJ = C .BYTE 'OB',$80+'J' ; C SET C+1 CERR = C .BYTE 'ER',$80+'R' ; C SET C+1 CEJECT = C .BYTE 'EJEC',$80+'T' ; C SET C+1 ; CSEDIT = C ; 1ST EDITOR COMMAND CLIST = C ; LIST OPTION .BYTE 'LIS',$80+'T' ; ; CEOPT = C ; LAST OPTION C SET C+1 .BYTE 'NE',$80+'W' ; C SET C+1 .BYTE 'DE',$80+'L' ; C SET C+1 .BYTE 'FIN',$80+'D' ; C SET C+1 .BYTE 'ENTE',$80+'R' C SET C+1 .BYTE 'LOA',$80+'D' ; C SET C+1 .BYTE 'SAV',$80+'E' ; ; C SET C+1 .BYTE 'NU',$80+'M' ; C SET C+1 .BYTE 'PRIN',$80+'T' ; C SET C+1 .BYTE 'RE',$80+'N' ; C SET C+1 .BYTE 'RE',$80+'P' ; C SET C+1 .BYTE 'SIZ',$80+'E' ; C SET C+1 .BYTE 'LOME',$80+'M' ; C SET C+1 .BYTE 'BY',$80+'E' ; C SET C+1 .BYTE 'DO',$80+'S' ; C SET C+1 .BYTE 'AS',$80+'M' ; C SET C+1 .BYTE 'BU',$80+'G' CEEDIT = C ; LAST EDITOR COMMAND ; C SET C+1 CSBUG = C ; 1ST DEBUG COMMAND ; CA = C ; A OPERAND (EDITOR & ASM) .BYTE $80+'A' ; C SET C+1 CM = C ; M OPERAND (EDITOR) .BYTE $80+'M' ; C SET C+1 .BYTE 'C',$80+'R' ; C SET C+1 .BYTE 'D',$80+'R' ; C SET C+1 .BYTE $80+'G' ; C SET C+1 .BYTE $80+'T' ; C SET C+1 .BYTE $80+'S' ; C SET C+1 .BYTE $80+'D' ; C SET C+1 .BYTE $80+'L' ; C SET C+1 .BYTE $80+'V' ; C SET C+1 CX = C ; X OPERAND (ASM) .BYTE $80+'X' ; C SET C+1 .BYTE $80+'C' CEBUG = C ; LAST DEBUG ; C SET C+1 CSOP = C ; 1ST OPERATOR CPLUS = C ; PLUS .BYTE $80+'+' ; C SET C+1 CMINUS = C ; MINUS .BYTE $80+'-' ; C SET C+1 CMUL = C ; MULTIPLY CLOC = C ; LOCATION COUNTER .BYTE $80+'*' ; C SET C+1 CDIV = C ; DIVIDE .BYTE $80+'/' ; C SET C+1 CAND = C ; AND .BYTE $80+'&' ; C SET C+1 CDQ = C ; DOUBLE QUOTE .BYTE $A2 ; C SET C+1 CSQ = C ; SINGLE QUOTE .BYTE $80+'''' ; C SET C+1 CLPRN = C ; LEFT PAREN .BYTE $80+'(' ; C SET C+1 CRPRN = C ; RIGHT PAREN .BYTE $80+')' ; C SET C+1 CDOL = C ; DOLLAR SIGN .BYTE $80+'$' ; C SET C+1 CSC = C ; SEMI COLON .BYTE $80+';' ; C SET C+1 CIMM = C ; IMMEDIATE OPERAND CFILE = C .BYTE $80+'#' ; C SET C+1 CEOL = C ; CARRIAGE RETURN .BYTE CR ; C SET C+1 CCOM = C .BYTE $80+',' ; C SET C+1 CDELIM = C ; DEBUG DELIMETER .BYTE DELIM+$80 ; C SET C+1 CY = C ; Y OPERAND (ASM) .BYTE $80+'Y' ; C SET C+1 CQ = C ; Q OPERAND (EDIT) .BYTE $80+'Q' ; C SET C+1 CIFDEL = C ; IF DELIMITER .BYTE $80+'@' CEOP = C ; LAST OP .BYTE 0,$80 ; END OF TABLE C SET C+2 CDUM = C .BYTE '??',$80+'?' .PAGE 'SYNTAX TABLE ADDRESSES' ; ; EDITOR SYNTAX TABLE ADDRESSES ; ESTBL .WORD _SLIST-1 .WORD _SCLR-1 .WORD _SDEL-1 .WORD _SFIND-1 .WORD _SENTER-1 .WORD _SLOAD-1 .WORD _SSAVE-1 .WORD _SNUM-1 .WORD _SPRINT-1 .WORD _SREN-1 .WORD _SREP-1 .WORD _SSIZE-1 .WORD _SLOMEM-1 .WORD _SBYE-1 .WORD _SDOS-1 .WORD _SASM-1 .WORD _SATBUG-1 ; ; ; ; DEBUG SYNTAX TABLE ADDRESS ; DSTBL .WORD _SA-1 .WORD _SM-1 .WORD _SCR-1 .WORD _SDR-1 .WORD _SG-1 .WORD _ST-1 .WORD _SS-1 .WORD _SD-1 .WORD _SL-1 .WORD _SV-1 .WORD _SX-1 .WORD _SC-1 ; ; ; ; ASSEMBLE DIRECTIVE SYNTAX TABLE ADDRESSES ; ADSTBL .WORD _SIF-1 .WORD _STITLE-1 .WORD _SPAGE-1 .WORD _SWORD-1 .WORD _SBYTE-1 .WORD _SDBYTE-1 .WORD _SEND-1 .WORD _SOPT-1 .WORD _STAB-1 .WORD _SORG-1 .WORD _SEQU-1 .PAGE ; ; ASTBL - SYNTAX ROUTINE ADDRS FOR ASM BY COMMAND TYPE ; ASTBL .BYTE 0,0 .WORD ASDIR-1 ; DIRECTIVE .WORD ASIMP-1 ; DIRECTIVE .WORD ASREL-1 ; RELATIVE .WORD ASMISC-1 ; MISC .WORD ASMULT-1 ; MULT ADDR .PAGE ; ; TOPTBL - TRIAL OP CODE TABLE ; TOPTBL .BYTE $00 ; BRK .BYTE $18 ; CLC .BYTE $D8 ; CLD .BYTE $58 ; CLI .BYTE $B8 ; CLV .BYTE $CA ; DEX .BYTE $88 ; DEY .BYTE $E8 ; INX .BYTE $C8 ; INY .BYTE $EA ; NOP .BYTE $48 ; PHA .BYTE $08 ; PHP .BYTE $68 ; PLA .BYTE $28 ; PLP .BYTE $40 ; RTI .BYTE $60 ; RTS .BYTE $38 ; SEC .BYTE $F8 ; SED .BYTE $78 ; SEI .BYTE $AA ; TAX .BYTE $A8 ; TAY .BYTE $BA ; TSX .BYTE $8A ; TXA .BYTE $9A ; TXS .BYTE $98 ; TYA ; .BYTE $90 ; BCC .BYTE $B0 ; BCS .BYTE $F0 ; BEQ .BYTE $30 ; BMI .BYTE $D0 ; BNE .BYTE $10 ; BPL .BYTE $50 ; BVC .BYTE $70 ; BVS ; .BYTE $20 ; JSR .BYTE $4C ; JMP EOP1 = *-TOPTBL ; # OF ENTRYS IN NON-MULTI ADDR OP TABLE TOPT2 ; .BYTE $01 ; ORA .BYTE $21 ; AND .BYTE $41 ; EOR .BYTE $61 ; ADC .BYTE $81 ; STA .BYTE $A1 ; LDA .BYTE $C1 ; CMP .BYTE $E1 ; SBC .BYTE $02 ; ASL .BYTE $22 ; ROL .BYTE $42 ; LSR .BYTE $62 ; ROR .BYTE $C2 ; DEC .BYTE $E2 ; INC .BYTE $A2 ; LDX .BYTE $A0 ; LDY .BYTE $82 ; STX .BYTE $80 ; STY .BYTE $E0 ; CPX .BYTE $C0 ; CPY .BYTE $20 ; BIT EOP2 = *-TOPT2 ; # OF ENTRIES IN OP TABLE .PAGE ; 'SYNTAX TABLES' ; ; SYNTAX TABLE OP CODES _ANTV = $00 ; ABSOLUTE NON-TERMINAL VECTOR ; FOLLOWED BY 2 BYTE ADDR-1 _ESRT = $01 ; EXTERNAL SUBROUTINE CALL ; FOLLOWED BY 2 BYTE ADDR-1 _OR = $02 ; ALTERNATIVE - BNF OR (]) _RTN = $03 ; RETURN (#) _VEXP = KWSTRT-1 ; SPECIAL NTV FOR EXPR () _SCODE = KWSTRT ; PUT FOLLOWING TOKEN IN OUTPUT ; ; ; ; ; DEFRA -64,+63,$C0 .PAGE 'SYNTAX TABLES' ; ; = EOL# ; _SDEL DEFRA _LNO DEFRA _OLNO .BYTE CEOL .BYTE _RTN ; ; = , ]&# ; _OLNO .BYTE CCOM DEFRA _LNO .BYTE _OR .BYTE _RTN ; ; = EXTERNAL SUBROUTINE CALL TO PROCESS LINE # ; _DECNUM _LNO .BYTE _ESRT .WORD _DEC-1 .BYTE _RTN ; ; ; ; ; = EOL# ; _SFIND .BYTE _ESRT .WORD _STR1-1 DEFRA _LNRANGE DEFRA _OA _SNEW _SCLR _SSIZE _SBYE _SDOS _SATBUG .BYTE CEOL .BYTE _RTN ; ; ; ; = EOL# ; _SREP .BYTE _ESRT .WORD _STR1-1 .BYTE _ESRT .WORD _STR2-1 DEFRA _LNRANGE DEFRA _OQA .BYTE CEOL .BYTE _RTN ; ; = ,Q],A]&# ; = ,A]&# ; _OQA .BYTE CCOM .BYTE CQ .BYTE _OR _OA .BYTE CCOM .BYTE CA .BYTE _OR .BYTE _RTN ; ; ; ; ; ; ; ; = ]] ; ]EOL# ; _SASM DEFRA _FEOL .BYTE _OR DEFRA _F1 DEFRA _FEOL .BYTE _OR DEFRA _F1 DEFRA _F1 DEFRA _FEOL .BYTE _OR .BYTE CEOL .BYTE _RTN ; ; = ]#. ; _LNRANGE DEFRA _LNO DEFRA _OLNO .BYTE _OR .BYTE _RTN ; ; = ,],# ; _F1 DEFRA _FILES .BYTE CCOM .BYTE _OR .BYTE CCOM .BYTE _RTN ; ; = EOL# ; _FEOL DEFRA _FILESPEC .BYTE CEOL .BYTE _RTN ; ; ; ; = # ; _SREL = *-1 _SJSR = *-1 _EXP DEFRA _EXPX .BYTE _SCODE,TEOE .BYTE _RTN _EXPX DEFRA _VALUE DEFRA _OPVAL .BYTE _RTN ; ; = ]&# ; _OPVAL DEFRA _OP DEFRA _EXPX .BYTE _OR .BYTE _RTN ; ; = ]$]' ; ]*]LABREF# ; _VALUE DEFRA _DECNUM .BYTE _OR .BYTE CDOL,_ESRT .WORD _HEXD-1 .BYTE _OR .BYTE CSQ,_ESRT .WORD _GCHAR-1 .BYTE _OR .BYTE CLOC,_ESRT .WORD _LOC-1 .BYTE _OR .BYTE _ESRT .WORD _LBLREF-1 .BYTE _RTN ; ; = *]/]+]&]-# ; _OP .BYTE CMUL .BYTE _OR .BYTE CDIV .BYTE _OR .BYTE CPLUS .BYTE _OR .BYTE CAND .BYTE _OR .BYTE CMINUS .BYTE _RTN ; ; ; ; = EOL]EOL# ; ; ; ; = EOL# ; _SPRINT _SLIST DEFRA _FILESPEC .BYTE CEOL .BYTE _OR DEFRA _OFILE _SREN _SNUM DEFRA _LNRANGE .BYTE CEOL .BYTE _RTN ; ; = ,]&# ; _OFILE DEFRA _FILESPEC .BYTE CCOM .BYTE _OR .BYTE _RTN ; ; ; ; ; = # ; _SLOAD _FILESPEC .BYTE CFILE .BYTE _ESRT .WORD _FSTR-1 .BYTE _RTN ; ; ; ; = EOL# ; _SENTER DEFRA _FILESPEC DEFRA _OM .BYTE CEOL .BYTE _RTN ; ; = ,M]&# ; _OM .BYTE CCOM .BYTE CM .BYTE _OR .BYTE _RTN ; ; = EXTERNAL SUBROUTINE CALL TO PROCESS ADDR ; _HEXNUM _ADR .BYTE _ESRT .WORD _HEX-1 .BYTE _RTN ; ; ; ; = < , ; _SSAVE .BYTE CFILE .BYTE _ESRT .WORD _FSTRM-1 DEFRA _ADR2 .BYTE _RTN ; ; ; = <,EOL# ; _SM _SV DEFRA _ADR _ADR2 .BYTE CDELIM DEFRA _ADR .BYTE CCOM ; ; = EOL# ; _SLOMEM DEFRA _ADR .BYTE CEOL .BYTE _RTN ; ; ; ; ; ; ; = = = EOL# ; ; _SG _SS _ST DEFRA _OADR _SX _SDR _SA .BYTE CEOL .BYTE _RTN ; ; ; ; ; = EOL]ADR>EOL# ; _SD _SL .BYTE CEOL .BYTE _OR DEFRA _ADR DEFRA _OADR2 .BYTE CEOL .BYTE _RTN ; ; = ]&# ; ; = ,]&# ; _OADR2 .BYTE CCOM _OADR DEFRA _ADR .BYTE _OR .BYTE _RTN ; ; ; ; = <EOL# ; ; _SC DEFRA _OADR _SCR .BYTE CDELIM DEFRA _DATA .BYTE CEOL .BYTE _RTN ; ; = ,]# ; _DATA .BYTE CCOM DEFRA _DATA .BYTE _OR DEFRA _HEXNUM DEFRA _OHEX .BYTE _RTN ; ; = ,]&# ; _OHEX .BYTE CCOM DEFRA _DATA .BYTE _OR .BYTE _RTN ; ; ; <PAGE> = <QSTR>]# ; _STITLE _SPAGE DEFRA _QSTR .BYTE _OR .BYTE _RTN ; ; ; ; <DBYTE> ; <DWORD> = <EXP><OWORD># ; _SDBYTE _SWORD .BYTE _VEXP DEFRA _OWORD .BYTE _RTN ; ; <OWORD> = , <WORD>]&# ; _OWORD .BYTE CCOM DEFRA _SWORD .BYTE _OR .BYTE _RTN ; ; ; ; <BYTE> = <BYTE1># ; ; _SBYTE DEFRA _BYTE1 .BYTE _RTN ; ; <BYTE1> = <QSTR><OBYTE>]<EXP><OBYTE># ; _BYTE1 DEFRA _QSTR DEFRA _OBYTE .BYTE _OR .BYTE _VEXP DEFRA _OBYTE .BYTE _RTN ; ; <OBYTE> = ,<BYTE1>]&# ; _OBYTE .BYTE CCOM DEFRA _BYTE1 .BYTE _OR .BYTE _RTN ; ; <QSTR> = '<STR2># ; _QSTR .BYTE CDQ .BYTE _ESRT .WORD _STR3-1 .BYTE _RTN ; ; <TAB> = <EXP>,<EXP>,<EXP># ; <=> ; <=*> = <EXP># ; <END> = # ; _STAB .BYTE _VEXP .BYTE CCOM .BYTE _VEXP .BYTE CCOM _SEQU _SORG .BYTE _VEXP _SEND .BYTE _RTN ; ; ; ; ; <IF> = <EXP><LABSTR> ; _SIF .BYTE _VEXP .BYTE CIFDEL .BYTE _ESRT .WORD _FSTR-1 .BYTE _RTN ; ; ; ; ; <OPT> = <OPT1># ; _SOPT DEFRA _OPT1 .BYTE _RTN ; ; <OPT1> = <ONO><LIST><OOPT># ; _OPT1 DEFRA _ONO DEFRA _LIST DEFRA _OOPT .BYTE _RTN ; ; <ONO> = NO]# ; <LIST> = OBJ]ERR]PAGE]SYM]LIST# ; _ONO .BYTE CNO,_OR,_RTN _LIST .BYTE COBJ,_OR .BYTE CERR,_OR .BYTE CEJECT,_OR .BYTE CLIST .BYTE _RTN ; ; <OOPT> = , <OPT1>]&# ; _OOPT .BYTE CCOM DEFRA _OPT1 .BYTE _OR .BYTE _RTN ; ; ; ; ; <JMP INST> = CLPRN<EXP>CRPRN ]<EXP> ; _SJMP = *-1 .BYTE CLPRN .BYTE _VEXP .BYTE CRPRN .BYTE _OR .BYTE _VEXP .BYTE _RTN ; ; ; ; <MULT ADDR TEST> = <INDX>]<INDY>]<IMM>]<ABSOLUTE><ACU># ; LEAVE ACU AS LAST THING ; _SMULT = *-1 ; ; <INDX> = CLPRN<EXP>CCOM CX CRPRN ; .BYTE CLPRN .BYTE _VEXP DEFRA _IND .BYTE _OR ; ; <IMM> = CIMM<EXP> ; .BYTE CIMM .BYTE _VEXP .BYTE _SCODE,TIMM .BYTE _OR ; ; <ABSOLUTE> = <EXP><ABS># ; .BYTE _VEXP DEFRA _ABS .BYTE _OR ; ; <ACU> = CA ; .BYTE _SCODE,TACU .BYTE CA .BYTE _RTN ; ; <IND> = ,X)]),Y# ; _IND .BYTE _SCODE,TINDX .BYTE CCOM .BYTE CX .BYTE CRPRN .BYTE _OR .BYTE _SCODE,TINDY .BYTE CRPRN .BYTE CCOM .BYTE CY .BYTE _RTN ; ; <ABS> = ,X],Y]# ; _ABS .BYTE _SCODE,TABSX .BYTE CCOM .BYTE CX .BYTE _OR .BYTE _SCODE,TABSY .BYTE CCOM .BYTE CY .BYTE _OR .BYTE _SCODE,TABS .BYTE _RTN .PAGE 'EXECUTION ADDRESS TABLES' ; ; EDITOR COMMANDS EXECUTION ADDRESS' ; EXTBL .WORD XLIST-1 .WORD XCLR-1 .WORD XDEL-1 .WORD XFIND-1 .WORD XENTER-1 .WORD XLOAD-1 .WORD XSAVE-1 .WORD XNUM-1 .WORD XPRINT-1 .WORD XREN-1 .WORD XREP-1 .WORD XSIZE-1 .WORD XLOMEM-1 .WORD BYELOC-1 .WORD XDOS-1 .WORD XASM-1 .WORD XATBUG-1 ; ; ; ; ; DEBUG COMMAND EXECUTION ADDRESSES ; DXTBL .WORD XA-1 .WORD XM-1 .WORD XCR-1 .WORD XDR-1 .WORD XG-1 .WORD XT-1 .WORD XS-1 .WORD XD-1 .WORD XL-1 .WORD XV-1 .WORD XX-1 .WORD XC-1 .PAGE ; ; AXTBL - ASEMBLER EXECUTION ROUTINES BY TYPE ; AXTBL .WORD AXCOM-1 ; COMMENT .WORD AXDIR-1 ; DIRECTIVE .WORD AXIMP-1 ; IMPLIED INSTRUCTION .WORD AXREL-1 ; RELATIVE .WORD AXMISC-1 ; MISCELLANEOUS .WORD AXMULTI-1 ; MULTI-ADDRESS ; ; ; ; ; ASM DIRECTIVE EXECUTION TABLE ; ADXTBL .WORD XIF-1 .WORD XTITLE-1 .WORD XPAGE-1 .WORD XWORD-1 .WORD XBYTE-1 .WORD XDBYTE-1 .WORD XEND-1 .WORD XOPT-1 .WORD XTAB-1 .WORD XORG-1 .WORD XEQU-1 .PAGE 'MEMORY MANAGER' ; LOCAL ; ; MEMORY MANAGEMENT CONSISTS OF EXPANDING AND ; CONTRACTING TO INFORMATION AREA POINTED TO ; BY THE ZERO PAGE POINTER TABLES. ROUTINES ; MODIFY THE ADDRESS IN THE TABLES AND ; MOVE DATA AS REQUIRED. THE TWO FUNDAMENTAL ; ROUTINES ARE 'EXPAND' AND 'CONTRACT' ; ; **** ; ; EXPAND- ; X = ZERO PAGE ADDRESS OF TABLE AT WHICH ; EXPANSION IS TO START ; Y = EXPANSION SIZE IN BYTES (LOW) ; A = EXPANSION SIZE IN BYTES (HIGH) ; ; EXPLOW - FOR EXPANSION < 256 BYTES ; SETS A = 0 ; ; EXPTXT - EXPAND AT STMCUR ; COMPLIMENT OF LENGTH IN A ; ; EXPTXT EOR #$FF ;COMPLEMENT RESULT TAY INY LDX #STMCUR ;POINT TO STMT CURRENT ; EXPLOW LDA #0 ; EXPAND STY ECSIZE ; SAVE EXPAND SIZE STA ECSIZE+1 ; SEC LDA MEMTOP ; TEST MEMORY TO BE FULL ADC ECSIZE TAY ; MEMTOP+ECSIZE+1 LDA MEMTOP+1 ADC ECSIZE+1 ; MUST BE LE CMP HIMEM+1 BCC _EXP2 ; HIMEM BNE _EXP1 CPY HIMEM BCC _EXP2 BEQ _EXP2 _EXP1 LDA #MEMFULL ;GET ERROR CODE JSR ERROR JSR PRTERR ; PRINT ERROR JMP ABRK ; ABORT ; _EXP2 SEC ; FORM MOVE LENGTH (MVLNG) LDA MEMTOP ; MOVE FROM ADR (MVFA) SBC 0,X ; MVLNG = MEMTOP-EXPAND ADR STA MVLNG LDA MEMTOP+1 ; MVFA(L) = EXP ADR (L) SBC 1,X STA MVLNG+1 ; MVFA(H) = EXP ADR(H) + MVLNG(H) CLC ; DURING MOVE MVLNG(L) ADC 1,X ; WILL BE ADDED SUCH STA MVFA+1 ; THAT MVFA = MEMTOP ; LDA 0,X ; SAVE PREMOVE EXPAND AT VALUE STA MVFA ; SET MVFA LOW STA SVESA ; FORM MOVE TO ADR (MVTA) ADC ECSIZE ; MVTA(L) = EXP ADR(L) + ECSIZE(L) STA MVTA ; MVTA(H) = (CARRY + EXP ADR(H) LDA 1,X ; +ECSIZE(H)) + MVLNG(H) STA SVESA+1 ADC ECSIZE+1 ; DURING MOVE MVLNG(L) ADC MVLNG+1 ; WILL BE ADDED SUCH THAT STA MVTA+1 ; MVTA = MEMTOP + ECSIZE ; _EXP3 LDA 0,X ; ADD ECSIZE TO ADC ECSIZE ; ALL TABLE ENTRIES STA 0,X ; FROM EXPAND AT ADR LDA 1,X ; TO HIMEM ADC ECSIZE+1 STA 1,X INX INX CPX #MEMTOP+2 BCC _EXP3 ; STA APHM+1 ; SET NEW APL LDA MEMTOP ; HI MEM TO STA APHM ; MEMTOP ; LDX MVLNG+1 ; X = MVLNG(H) INX ; PLUS ONE LDY MVLNG ; Y=MVLNG(L) BNE _EXP6 ; TEST ZERO LENGTH BEQ _EXP7 ; BR IF LOW = 0 ; _EXP4 DEY ; DEC MVLNG(L) DEC MVFA+1 ; DEC MVFA(H) DEC MVTA+1 ; DEC MVTA(H) ; _EXP5 LDA (MVFA),Y ; MVFA BYTE STA (MVTA),Y ; TO MVTA _EXP6 DEY ; DEC COUNT LOW BNE _EXP5 ; BR IF NOT ZERO ; LDA (MVFA),Y ; MOVE THE ZERO BYTE STA (MVTA),Y ; _EXP7 DEX ; IF MVLNG(H) IS NOT BNE _EXP4 ; ZERO THEN MOVE 256 MORE ; ELSE RTS ; DONE .PAGE ; ; CONTRACT ; X = ZERO PAGE ADR OF TABLE AT WHICH ; CONTRACTION WILL START ; Y = CONTRACT SIZE IN BYTES (LOW) ; A = CONTRACT SIZE IN BYTES (HI) ; CONTLOW ; SETS A = 0 ; ; ; CONTXT - CONTRACT AT STMCUR ; LENGTH IN A ; CONTXT TAY LDX #STMCUR CONTLOW LDA #0 ; CONTRACT STY ECSIZE ; SAVE CONTRACT SIZE STA ECSIZE+1 ; SEC ; FORM MOVE LENGTH (LOW) LDA MEMTOP SBC 0,X ; MVLNG(L) = $100- ; EOR #$FF ; (MEMTOP(L)) - CON AT VALUE (L) TAY ; THIS MAKES START Y AT INY ; MOVE HAVE A 2'S COMPLIMENT STY MVLNG ; REMAINDER IN IT LDA MEMTOP+1 ; FORM MOVE LENGTH(HIGH) SBC 1,X STA MVLNG+1 ; LDA 0,X ; FORM MOVE FROM ADR (MVFA) SBC MVLNG ; MVFA = CON AT VALUE STA MVFA ; MINUS MVLNG(L) LDA 1,X ; DURING MOVE MVLNG(L) SBC #0 ; WILL BE ADDED BACK INTO STA MVFA+1 ; MVFA IN (IND),Y INST ; STX MVTA ; TEMP SAVE OF CON AT DISPL ; _CONT1 SEC ; SUBTRACT ECSIZE FROM LDA 0,X ; ALL TABLE ENTRY FROM SBC ECSIZE ; CON AT ADR TO HIMEM STA 0,X LDA 1,X SBC ECSIZE+1 STA 1,X INX INX CPX #MEMTOP+2 BCC _CONT1 STA APHM+1 ; SET NEW APL LDA MEMTOP ; HI MEM TO STA APHM ; MEMTOP ; LDX MVTA ; LDA 0,X ;FORM MOVE TO ADR (MVTA) SBC MVLNG ; MVTA = NEW CON AT VALUE STA MVTA ; MINUS MVLNG (L) LDA 1,X ; DURING MOVE MVLNG(L) SBC #0 ; WILL BE ADDED BACK INTO STA MVTA+1 ; MVTA IN (INO),Y INST ; FMOVER LDX MVLNG+1 ; GET MOVE LENGTH HIGH INX ; INC SO MOVE CAN BNE LDY MVLNG ; GET MOVE LENGTH LOW BNE _CONT2 ; IF NOT ZERO GO DEX BNE _CONT2 RTS ; _CONT3 INC MVFA+1 ;INC MVFA(H) INC MVTA+1 ; INC MVTA(H) ; _CONT2 LDA (MVFA),Y ; GET MOVE FROM BYTE STA (MVTA),Y ; SET MOVE TO BYTE INY ; INCREMENT COUNT LOW BNE _CONT2 ; BR IF NOT ZERO ; _CONT4 DEX ; DECREMENT COUNT HIGH BNE _CONT3 ;BR IF NOT ZERO RTS ; ELSE DONE .PAGE 'EXECUTE DOS' ; ; ; ; ; XDOS - EXECUTE DOS COMMAND ; XDOS JMP (DOSLOC) .PAGE 'EXECUTE DEBUG MONITOR START' ; ; XATBUG - EXECUTE DEBUG ; SET BREAK VECTOR ; XATBUG LDY #7 ; GET LARGEST DEVICE # JSR CLALL7 ; CLOSE ALL DEVICES BUG1 LDA #DMODE ; SET DEBUG MODE STA MODEFLG ; X JMP DSYN2 .PAGE 'EXECUTE NUMBER' ; ; XNUM - EXECUTE NUMBER COMMAND ; XNUM LDA #AUTON ; TURN AUTO FLAG ON STA AUTOFLG ; X ; JSR PNUM ; SET UP NUMBER PARMS BCC _NDONE ; BR IF HAVE SLNO ; ; ELSE SET UP DEFAULT SLNO ; LDA #0 ; GET 1ST LINE # STA TSLNUM ; X STA TSLNUM+1 ; X JSR GETSTMT ; X ; ; FIND LAST LINE # ; _NUM2 JSR TSTTEND ; WERE THERE ANY STMTS? BCS _NUM1 ; IF YES, AT END OF STMTS ; LDY #0 ; X LDA (STMCUR),Y ; SAVE LINE # STA TSLNUM ; INY LDA (STMCUR),Y ; STA TSLNUM+1 ; JSR GETLL ; GET NEXT LINE JSR GNXTL ; ; JMP _NUM2 _NUM1 CLC ; SET START LINE # LDA TSLNUM ; LAST LINE # + INCR ADC LNINCR ; STA CURLN LDA TSLNUM+1 ; ADC LNINCR+1 ; X STA CURLN+1 _NDONE RTS .PAGE ; ; PNUM - SET UP PARMS FOR NUM & REN ; ; PNUM LDA #10 ; SET DEFAULT INCR STA CURLN ; AND START LINE # STA LNINCR ; X LDA #0 STA CURLN+1 ; X STA LNINCR+1 ; X ; JSR GETCODE ; GET TOKEN CMP #CEOL ; IS IT END OF LINE BEQ _PSET ; IF YES, DONE ; ; ELSE HAVE AT LEAST 1 NUMBER ; JSR GETCODE ; SET # AS NEW INCR STA LNINCR ; X JSR GETCODE ; X STA LNINCR+1 ; X ; JSR GETCODE ; GET NEXT CODE CMP #CEOL ; IS IT END OF LINE BEQ _PSET ; IF YES, DONE ; LDA LNINCR ; MOVE # TO START LINE # STA CURLN ; X LDA LNINCR+1 ; X STA CURLN+1 ; X ; JSR GETC1 ; SKIP THEX CODE STA LNINCR ; SET AS NEW INCR JSR GETCODE ; X STA LNINCR+1 ; X CLC ; SET START LINE # FOUND RTS _PSET SEC ; SET NEED DEFAULT SLNO RTS .PAGE 'EXECUTE RENUMBER' ; ; XREN - EXECUTE RENUMBER COMMAND ; XREN JSR PNUM ; SET UP RENUM PARMS ; ; GET 1ST LINE ; LDA #0 STA TSLNUM ; SET LINE # TO FIND TO 0 STA TSLNUM+1 ; X JSR GETSTMT ; GET 1ST LINE ADDR ; ; ; RENUMBER _REN2 JSR TSTTEND ; TST FOR END OF TEXT BCS _REN3 ; IF AT END, THEN DONE ; LDY #0 ; GET INDEX INTO LINE LDA CURLN ; SET LINE # = CURLN STA (STMCUR),Y ; Y LDA CURLN+1 ; X INY ; X STA (STMCUR),Y ; X ; JSR UPCUR ; INCR CURLN ; JSR GETLL ; GET NEXT LINE JSR GNXTL ; X JMP _REN2 ; REPEAT .PAGE 'EXECUTE DELETE' ; ; XDEL - EXECUTE DELETE ; XDEL JSR LRANG1 ;SET UP LINE # RANGE BCC DELC ;IF 1ST LINE EXISTS, NO ERROR ; LDA #ERNLN ;ELSE PRINT ERROR JSR EDERR ; DELC JSR TLEND ;TEST FOR END OF LINE RANGE BCS _DRTN ; JSR DELLN ;DELETE LINE JMP DELC ;REPEAT ; _REN3 _DRTN RTS .PAGE 'EXECUTE PRINT' ; ; XPRINT - EXECUTE PRINT ; XPRINT LDA #LNUMOFF ; SET TYPE OF LIST JSR LISTJN ;DO LIST WAITCR JSR GLGO ; WAIT FOR INPUT JSR TSTBRK BNE _XPDONE LDY #0 LDA (INBUFF),Y CMP #CR BNE WAITCR _XPDONE RTS .PAGE 'EXECUTE LIST' ; ; XLIST - EXECUTE LIST (FOR EDITOR) ; XLIST LDA #LNUMON ; SET TYPE OF LIST TO LIST = * LISTJN STA LTYPFLG ; LIST LINE # ; LDA #$7F STA DSPFLG ; SET NON-DISPLAY MODE ; JSR PRCR ; PRINT CARRIDGE RETURN ; JSR GETCODE ; GET TOKEN FROM OUTBUFF CMP #CFILE ; IS IT FILESPEC CODE? BNE _LIST1 ; IF NOT, SKIP FILE HANDLING ; ; OPEN FILE FOR LIST ; JSR FLIST ; HANDLE FILESPEC ; JSR _LIST2 ; GO LIST ; ; CLOSE DEVICE ; LDA LISTDTD ; GET LIST DEVICE # JSR CLSYSD ; GO CLOSE IT ; LDA #SCRDV ; RESET OUTPUT DEVICE TO SCREEN STA LISTDTD ; X RTS .PAGE _LIST2 JSR GETCODE ; GET NEXT TOKEN CMP #CEOL ; IS IT COMMA? BEQ _LIST1 ; IF YES, BR JSR GETCODE ; GET NEXT CODE _LIST1 JSR LRANGE ; SET UP LINE # RANGE ; ; LISTC JSR TSTBRK ;TEST FOR BREAK BNE _LRTN ; DONE IF BREAK ; JSR TLEND ;TEST FOR END OF LINE RANGE BCS _LRTN ; IF AT END, BR _LGO JSR LIST1 ; GO LIST ONE LINE JSR TSTBRK ; TEST FOR BRK BNE _LRTN ; IF BRK, RETURN JSR GETLL ; GET LINE LENGTH JSR GNXTL ;GET NEXT LINE ADDR JMP LISTC ; GO DO THIS ONE _LRTN LDA #0 STA DSPFLG ; SET DISPLAY MODE ; RTS .PAGE ; ; LIST1 - LIST ONE LINE ; LIST1 JSR MOVLIN ; MOVE LINE TO LBUFF JMP INBOUT ; OUTPUT DATA POINTED TO BY INBUFF .PAGE ; ; MOVLIN - MOVE TEXT LINE POINTED TO BY STMCUR TO LBUFF ; ; ; ON EXIT OUTCNT - POINTS TO LAST BYTE OF OUTPUT ; ; MOVLIN LDA #0 ; SET # OF BYTES IN BUFFER TO ZERO STA OUTCNT ; X JSR INTLBF ; SET UP INBUFF LDA LTYPFLG ; GET LISTING TYPE FLAG BNE MOVTXT ; IF NOT 0, SKIP LINE # LIST ; LDY #0 ; MOVE LINE # TO FR0 LDA (STMCUR),Y ; X STA FR0 ; X INY ; X LDA (STMCUR),Y ; Y STA FR0+1 ; X ; JSR IASC ; CONVERT TO ASCII IN LBUFF JSR INTLBF ; RESET LBUFF LDY #$FF ; INIT INDEX INTO LBUFF _MOVL INC OUTCNT ; INCR # BYTES IN BUFFER INY ; POINT NEXT BYTE LDA (INBUFF),Y ; GET BYTE BPL _MOVL ; IF MSB OFF, THEN MOVE BYTES AND #$7F ; AND OUT MSB STA (INBUFF),Y ; SAVE ; ; ; ; MOVTXT - MOVE TEXT LINE POINTED TO BY ; STMCUR TO LBUFF ; MOVTXT LDY #2 ; GET LINE LENGTH LDA (STMCUR),Y ; X SEC ; GET # OF CHARS TO MOVE SBC #3 ; X TAX ; PUT IN X AS COUNTER STY CIX ; SET LINE INDEX ; _LM1 INC CIX ; GET CHAR FROM LINE LDY CIX ; X LDA (STMCUR),Y ; X LDY OUTCNT ; PUT IT IN BUFFER STA (INBUFF),Y ; X INC OUTCNT ; POINT TO NEXT BUFFER BYTE DEX BNE _LM1 RTS .PAGE ; ; INBOUT - OUTPUT DATA POINTED TO BY INBUFF ; ; ON ENTRY INBUFF - POINTS TO DATA ; OUTCNT - LENGTH ; INBOUT LDY #0 ; GET INDEX STY CIX ; SAVE _INB LDA (INBUFF),Y ; GET CHAR PHA JSR PRCHAR ; PRINT IT PLA INC CIX ; INCR INDEX LDY CIX ; GET INDEX CMP #CR ;ARE WE AT END ? BNE _INB ; IF NOT, DO AGAIN RTS .PAGE ; ; STRMOV - MOVE STRING TO LBUFF AND PUT EOL AT END ; ; ON ENTRY A - LENGTH ; OUTBUF - CONTAINS STRING ; STRMOV JSR GETC2 ; GET LENGTH TO A-REG STA ZT1 ; SAVE LENGTH LDX #0 ; SET LBUFF DISPL _STRM1 JSR GETCODE ; GET A STRING CHAR STA FNBUFF,X ; STORE NAME BYTE INX ; INCR INDEX DEC ZT1 ; DECR LENGTH BNE _STRM1 ; LOOP IF NOT DONE ; LDA #CR ; GET CARRRIDE RETURN STA FNBUFF,X ; END OF NAME STRING RTS .PAGE ; ; LRANGE - SET UP LINE # RANGE ; ; A - CONTAINS 1ST TOKEN IN LINE RANGE ; OUTBUFF - CONTAINS COMMAND ; LRANG1 JSR GETCODE ;GET 1ST TOKEN LRANGE ; ; SET DEFAULT RANGE ; LDY #0 ; SET TABLE SEARCH LINE STY TSLNUM ; NUMBER TO ZERO STY TSLNUM+1 ; X DEY STY LELNUM ; SET LAST LIST LINE # TO MAX STY LELNUM+1 ; X ; ; GET 1ST LINE ; CMP #THEX2 ; IS CHAR = NUMBER CODE BNE _LRAN3 ; IF NOT, THEN NO LINE RANGE ; JSR GETCODE ;GET STARTLINE # FROM COMMAND LINE STA TSLNUM STA LELNUM ; SET LAST LINE # = 1ST JSR GETCODE ; X STA TSLNUM+1 ; X STA LELNUM+1 ; X ; ; SET UP LAST LINE # ; JSR GETCODE ; GET NEXT PARM CMP #CEOL ;IS IT EOL ? BEQ _LRAN3 ; IF EQUAL, THEN HAVE LAST LINE # = 1ST _LRAN2 JSR GETCODE ; GET NEXT TOKEN CMP #THEX2 ; IS IT # CODE BNE _LRAN4 ; IF NOT, LINE RANGE COMPLETE JSR GETCODE STA LELNUM JSR GETCODE ; X STA LELNUM+1 ; X JMP _LRAN1 _LRAN4 DEC COX _LRAN3 DEC COX ; BACK UP _LRAN1 JMP GETSTMT ; GET ADDR OF 1ST LINE .PAGE ; ; GETCODE - GET TOKEN FROM OUTPUT ; ; GETC1 - INCR 1 AND GET TOKEN ; ; GETC2 - INCR 2 AND GET TOKEN ; GETC3 INC COX GETC2 INC COX GETC1 INC COX GETCODE LDY COX ; GET INDEX INC COX ; INCR INDEX LDA (OUTBUFF),Y ; GET CHAR RTS ; ; ; ; ; ; ; GETIN - GET NEXT CHAR FROM INBUFF ; GETIN LDY CIX LDA (INBUFF),Y INC CIX RTS .PAGE 'EXECUTE FIND & REPLACE' ; ; XREP - EXECUTE FIND ; XREP JSR INCPST ; INCR PAST STRING 1 BEQ _FDONE ; IF STR1 NULL, THEN DONE STA STR1LNG ; SAVE LENGTH OF STRING 1 JSR INCPST ; INCR PAST STRING 2 STA STR2LNG ; SAVE LENGTH ; LDA #REPON ; GET REPLACE FLAG BNE _FR ; ; ; ; ; XFIND - EXECUTE FIND ; XFIND JSR INCPST ; INCR PAST STR STA STR1LNG ; SAVE STRING LENGTH ; ; LDA #FINDON ; GET FIND FLAG _FR STA REPFLG ; SET FLAG JSR FRINIT ; DO INIT ; ; DO FIND ; FINDC JSR TSTBRK ;IF BREAK BIT, BNE _FDONE ; WE ARE DONE ; JSR TLEND ; ARE WE AT END OF LINES? BCS _FDONE ; IF YES, THEN DONE ; LDY #3 ; INIT LINE INDEX STY LINDEX ; X _FIND2 JSR LSEARCH ; SEARCH LINE FOR STR BCS _FIND1 ; IF NOT FOUND SEARCH NEEXT LINE ; LDA REPFLG ; ARE WE DOING REPLACE? BNE CKREP ; IF YES GO DO IT ; JSR LIST1 ; ELSE, LIST LINE LDA AQ1FLG ; GET OCCURENCE FLAG BEQ _FDONE ; IF SET FOR 1ST OCCURENCE THEN DONE ; _FIND1 JSR GETLL ; GET NEXT LINE JSR GNXTL ; X JMP FINDC _FDONE RTS .PAGE ; ; ; CKREP LDA AQ1FLG ; GET FLAG BPL DOREP ; IF QUERRY NOT SET, SKIP ; ; QUERRY FOR REPLACE ; QUERRY JSR LIST1 ; LIST LINE _Q1 LDA #'? ; GET TEMP PROMPT JSR PRCHAR ; PRINT PROMPT JSR GLGO ; GET A LINE JSR TSTBRK BEQ _Q2 JMP ESYN2 _Q2 ; LDY #0 ; GET 1ST CHAR LDA (INBUFF),Y ; X CMP #CDO ; IS IT CHAR FOR REPLACE BEQ DOREP ; IF YES, GO DO REPLACE ; CMP #CNODO ; IS IT CHAR FOR NO REPLACE BNE _Q1 ; IF NOT, REPEAT QUERRY INC LINDEX ; INCR PAST STARTOF STRING BNE _FIND2 ; IF YES, SEARCH REST OF LINE ; ; DOREP ; ; SET NEW LINE LENGTH ; LDA STR1LNG ; GET CONTRACT/EXPAND LENGTH SEC SBC STR2LNG ; X ; ; LINLNG = LINLNG - (STR1LNG - STR2LNG) ; STA ZT1 LDA LINLNG SEC SBC ZT1 LDY #2 STA (STMCUR),Y ; ; SAVE STMCUR ; LDA STMCUR PHA LDA STMCUR+1 PHA ; ; POINT TO END OF STRING IN LINE ; (STMCUR = STMCUR + LINDEX) ; LDA #0 ; IF STRING 2 IS NULL, SET CARRY CMP STR2LNG ; TO ADD 1 FOR CONTRACT LDA LINDEX JSR GNXTL1 ; ; EXPAND OR CONTRACT ; LDA ZT1 ; GET DIFFERENCE PHA ; SAVE DIFFERENCE BEQ _REP ; DO REPLACE (OLD=NEW) BPL _RCON ; CONTRACT (OLD>NEW) ; ; ; JSR EXPTXT ; ELSE EXPAND (OLD<NEW) JMP _REP ; GO REPLACE ; _RCON JSR CONTXT ; CONTRACT ; _REP ; ; SET NEW LINE INDEX = END OF NEW STRING ; PLA ; GET DIFFERENCE STA ZT1 ; GET NEW LINE INDEX LDA LINDEX ; X SEC ; X SBC ZT1 ; X STA LINDEX ; X INC LINDEX ; INCR LINE INDEX ; ; RESTORE STMCUR ; PLA STA STMCUR+1 PLA STA STMCUR ; ; MOVE IN NEW STRING ; TVS CIX - START OF STRING IN LINE ; LDA #0 ; SET OUTBUF INDEX TO ZERO STA COX ; X JSR INCPST ; INCR OVER STR1 ; JSR GETC2 ; INC COX TO START OF STR2 TAX ; GET STR2 LEN AS COUNTER BEQ _REP3 ; IF STR2 IS NULL, THEN CR INC TVSCIX ; POINT TO STRAT OF REPLACED STR _REP2 LDY COX ; GET REPLACEMENT CHAR LDA (OUTBUFF),Y ; X LDY TVSCIX ; PUT IN LINE STA (STMCUR),Y ; X INC COX ; INCR OUTBUF POINTER INC TVSCIX ; INCR LINE POINTER DEX ; DEC COUNT BNE _REP2 ; IF MORE TO DO, DO IT ; _REP3 LDA AQ1FLG ; GET OCCURENCE FLAG BEQ _NFND ; IF SET TO 1 THEN DONE JMP _FIND2 ; SEARCH REST OF LINE .PAGE ; ; LSEARCH - SEARCH LINE IN LBUFF FOR STRING ; ; ON EXIT CARRY CLEAR - IF MATCH FOUND ; CARRY SET IF NO MATCH FOUND ; ; ; LSEARCH JSR GETLL ; GET LINE LENGTH STA LINLNG ; SAVE IT DEC LINDEX ; INIT LINE INDEX ; _LS1 LDY #2 ; INIT POINTER TO START OF STRING-1 STY COX LDA LINDEX ; SAVE (IF MATCH, THIS IS START OF STRING-1 STA TVSCIX ; X ; _LS2 INC COX ; POINT TO NEXT STRING CHAR LDY COX ; X CPY STRDEX ; ARE WE AT END OF LINE BCS _FND ; IF YES, WE FOUND IT ; LDA (OUTBUFF),Y ; GET STRING CHAR ; ; INC LINDEX ; INCR LINE POINTER LDY LINDEX ; GET INDEX CPY LINLNG ; ARE WE AT END OF LINE BCS _NFND ; IF YES, NO MATCH FOUND ; CMP (STMCUR),Y ; DOES STR CHAR = LINE CHAR? BEQ _LS2 ; IF = TRY NEXT STR CHAR FOR MATCH LDY TVSCIX ; GET OLD POSITION IN LINE INY ; INCR ONE CHARACTER STY LINDEX ; SET AS CURRENT POSITION IN LINE BNE _LS1 ; BR ALWAYS ; _FND CLC ; CLEAR FOR FOUND ; _NFND RTS .PAGE ; ; FRINIT - INIT FOR FIND AND REPALCE ; FRINIT JSR LRANG1 ; SET UP LINE RANGE ; ; SET ALL OR 1ST OCCURENCE OR QUERRY ; JSR GETCODE ; GET THE TOKEN CMP #CEOL ; IF AT END OF LINE BEQ _SET1 ; THEN SET 1ST OCCURENCE JSR GETCODE LDX #SETQ ; SET FOR QUERRY CMP #CA ; IS IT A? BNE _SETIT ; _SETA LDX #SETA ; SET ALL OCCURENCES BPL _SETIT ; _SET1 LDX #SET1 ; SET 1ST OCCURENCE _SETIT STX AQ1FLG ; SET Q, A OR 1ST ; LDA #LNUMON ; SET LIST TYPE FOR LINE#'S STA LTYPFLG ; X ; LDX STR1LNG ; GET STRING LENGTH INX ; POINT TO END OF STRING IN OUTBUFF INX ; X INX ; X STX STRDEX ; SAVE AS FOR END OF STR TEST RTS .PAGE ; ; INCPST - INCREMENT OUTPUT INDEX PAST STRING ; ; ON EXIT A - CONTAINS LENGTH ; INCPST JSR GETC2 ; GET LENGTH PHA ; SAVE IT CLC ; POINT PAST STRING ADC COX ; X STA COX ; X PLA ; GET LENGTH RTS .PAGE 'EXECUTE STATUS' ; ; XSIZE - ; XSIZE LDA LOMEM ; PRINT LOMEM LDY LOMEM+1 ; X JSR PRHEX2 ; X ; JSR PRBLK3 ; PRINT BLANKS ; LDA TXTEND ; PRINT TOP OF TEXT ADDR LDY TXTEND+1 ; X JSR PRHEX2 ; X ; JSR PRBLK3 ; PRINT BLANKS ; LDA HIMEM ; PRINT HIGH MEM LDY HIMEM+1 ; X JSR PRHEX2 ; ; JMP PRCR .PAGE 'EXECUTE LOMEM' ; ; XLOMEM - SET LOW MEM ; XLOMEM LDA LOMFLG ; IS LOW MEM COMMAND VALID BNE _LMERR ; IF NOT, ERROR ; JSR GETC1 ; GET VALUE LOW STA LMSAV ; SET NEW LOW MEM JSR GETCODE ; X STA LMSAV+1 JMP XNEW ; SET UP TABLE PTRS ; _LMERR LDA #ERLMEM JSR ERROR .PAGE 'EXECUTE ENTER' ; ; XENTER - EXECUTE ENTER ; XENTER JSR FLOAD2 ; HANDLE FILESPEC JSR GETCODE ; GET NEXT CODE CMP #CEOL ; IS IT EOL? BNE _NCLR ; IF NOT, DON'T CLEAR JSR XCLR ; ELSE CLEAR ; _NCLR JMP ESYNTAX .PAGE 'EXECUTE LOAD OBJECT' ; ; XLOAD - EXECUTE LOAD ; XLOAD JSR FLOAD2 ; OPEN ENTER DEVICE ; JSR GOBJ ; CHECK THE 2 LOAD CHARACTERS CMP #LCHK1 BNE __LERR JSR GOBJ CMP #LCHK2 BNE __LERR ; _LOAD2 JSR GOBJ ; GET OBJECT STA MVFA JSR GOBJ STA MVFA+1 JSR GOBJ ; GET END ADDR FROM FILE STA MVFEA JSR GOBJ STA MVFEA+1 _LOAD JSR FAGET ; TEST ADDRS BCS _LOAD2 ; AT END OF FIRST SEGMENT? JSR GOBJ ; GET BYTE LDY #0 ; SAVE IT STA (MVFA),Y JSR INCMVF ; INC ADDR JMP _LOAD ; ; ; _LEOF LDX ENTDTD ; CLOSE FILE _LEOF1 STX IODVC JMP CLSYSD ; ;; __LERR LDA #ERLOAD JSR ERROR ; .PAGE ; ; ; GOBJ - GET BYTE FROM OBJECT FILE ; ; ON EXIT A - OBJECT BYTE ; ; CC = 0 IF END OF FILE ; CC NOT = 0 IF NOT END OF FILE ; GOBJ LDX ENTDTD ; GET A BYTE LDA #ICGBC ; X JSR GPCHAR ; X BEQ _LEOF ; BR IF EOF LDY #0 LDA (INBUFF),Y LDX #$FF ; SET NOT = FLAG _GOBJ RTS .PAGE 'EXECUTE SAVE OBJECT' ; ; XSAVE - EXECUTE SAVE OBJECT ; XSAVE INC COX ; INCR OUTPUT INDEX JSR FOBJ ; OPEN OBJECT FILE JSR GETC1 ; POINT TO START OF ADDR JSR FADR ; SET UP MOVE TO & MOVE FROM ADDR ; LDA #LCHK2 ; WRITE LOAD CHECK CHAR FILL LDX #LCHK1 ; X JSR HPUTO2 ; LDA MVFA+1 ; OUTPUT START ADDR LDX MVFA ; X JSR HPUTO2 LDA MVFEA+1 ; OUTPUT END ADDR LDX MVFEA ; X JSR HPUTO2 _SAVE JSR FAGET2 ; GET BYTE BCS _SEOF ; IF AT EOF, BR ; LDX OBJDTD ; OUTPUT BYTE TO OBJECT FILE LDA #ICPBC JSR GPCHAR JMP _SAVE ; REPEAT ; ; _SEOF LDX OBJDTD ; CLOSE FILE BNE _LEOF1 .PAGE ; ; TLEND - TEST FOR END OF LINE RANGE ; ; ON EXIT CARRY SET IF AT END ; CARRY CLEAR IF NOT ; ; TLEND JSR TSTTEND BCS _TLN JSR TSTLST _TLN RTS .PAGE ; ; TSTTEND - TEST TO SEE IF WE ATE AT END OF TEXT ; ; ON EXIT CARRY SET IF AT END OF TABLE ; CARRY CLEAR IF NOT TSTTEND LDA STMCUR+1 ;GET CURRENT STMT ADDR HIGH CMP TXTEND+1 ; CMP TO END OF TXT HIGH BCC _TPASS ; IF < THEN RETURN PASS BNE _TFAIL ; IF NOT = THEN RETURN FAIL ; ELSE TEST LOW ORDER BYTE LDA STMCUR CMP TXTEND _TPASS _TFAIL RTS .PAGE ; ; TSTLST - TEST TO SEE IF WE ARE PAST LAST LINE # ; ; ON EXIT CARRY SET IF PAST LAST LINE # ; CARRY CLEAR IF NOT ; ; TSTLST LDY #1 ;COMP CURRENT STMT # LDA (STMCUR),Y ; WITH LAST LINE # CMP LELNUM+1 ; IF CUR <= LAST BCC _LEND ; THEN RETURN PASS BNE _LEND ; ELSE RETURN FAIL DEY ; X LDA (STMCUR),Y ; X CMP LELNUM ; X BEQ _LPASS ; IF = THEN PASS _LEND RTS _LPASS CLC RTS .PAGE 'EXECUTE DISPLAY' ; ; XD - EXECUTE DISPLAY ; XD ; ; SET DEFAULT START AND END ADDR ; (DEFAULT START ALREADY SET) ; ; JSR SDEND ; SET DISPLAU END ADDR ; JSR GETCODE ; GET TOKEN CMP #CEOL ; IS IT EOL? BEQ _D3 ; IF YES, S&E ADDRS DONE ; ; GET NEW START & DEFAULT END ADDR ; ; JSR GETCODE ; GET START ADDR FROM LINE STA DSADR JSR GETCODE STA DSADR+1 ; JSR SDEND ; SET DEFAULT END ; JSR GETCODE ; GET TOKEN CMP #CEOL ; IS IT EOL BEQ _D3 ; IF YES, S&E ADDRS DONE ; ; GET END ADDRS ; JSR GETC1 ; GET END ADDR FROM LINE STA DEADR ; X JSR GETCODE STA DEADR+1 ; X _D3 ; ; SAVE START ADDR FOR CHANGE ; LDA DSADR STA CSADR LDA DEADR+1 STA CSADR+1 .PAGE ; ; PRINT START ADDR ; _D1 JSR PRCR ; PRINT CARRIDGE RETURN ; LDA DSADR LDY DSADR+1 JSR PRADRB ; PRINT ADDR + BLANK ; _D2 LDY #0 ; GET DATA BYTE LDA (DSADR),Y ; X JSR PRHEXB ; PRINT # & BLANKS ; ; JSR TSTBRK ; IF BREAK BNE _DDONE ; THEN END ; LDA DSADR+1 ; GET CURRENT ADDR FOR END TEST LDY DSADR ; ; INCR TO NEXT ADDR ; INC DSADR ; GET NEXT ADDR BNE _D5 ; X INC DSADR+1 ; X _D5 ; ; TEST FOR END ; CMP DEADR+1 ; IF ADDR FOR INCR IS BNE _D4 ; = TO END ADDR CPY DEADR ; THEN DONE BEQ _DDONE ; _D4 ; LDA DSADR ; IF ADDR ENDS IN 0 OR 8 LSRA ; THEN PRINT ADDR AGAIN BCS _D2 ; ELSE PRINT NEXT DATA LSRA BCS _D2 LSRA BCS _D2 BCC _D1 ; ; ; _DDONE RTS .PAGE ; ; SDEND - SET DISPLAY END ADDR ; ; ENDADDR = START ADDR +7 ; SDEND CLC LDA DSADR ADC #7 STA DEADR LDA DSADR+1 ADC #0 STA DEADR+1 RTS .PAGE 'EXECUTE DISPLAY OR CHANGE REGISTERS' ; ; XDR - EXECUTE DISPLAY REGISTERS ; XDR JSR PRBLK3 ; PRINT BLANKS LDX #0 ; INITIALIZE _XDRLP STX ZT1 ; UPDATE CNTR LDA XDRCH,X ; GET REG. NAME CHAR. JSR PRCHAR ; PRINT IT LDA #'= JSR PRCHAR ; PRINT "=" LDX ZT1 LDA URA,X ; GET... JSR PRHEXB ; ...& PRINT REG VALUE LDX ZT1 INX ; BUMP CNTR CPX #5 ; DONE? BNE _XDRLP ; NO RTS ; YES ; XDRCH .BYTE 'AXYPS' ; ; ; ; ; ; ; XCR - EXECUTE CHANGE REGISTER ; XCR LDA #.LOW.UREG ; SET CHANGE ADDR TO POINT STA CSADR ; TO USER'S REGISTER'S LDA #.HIGH.UREG ; X STA CSADR+1 ; X BEQ _C3 ; JOIN CHANGE .PAGE 'EXECUTE CHANGE' ; ; XC - CHANGE DATA IN MEMORY ; XC JSR GETCODE ; GET 1ST TOKEN CMP #THEX2 ; IS ADDR PRESENT BNE _C2 ; IF NOT, USE CURRENT ADDR ; JSR GETCODE ; ELSE GET START ADDR FROM LINE STA CSADR ; X JSR GETCODE ; X STA CSADR+1 ; X _C3 INC COX ; POINT TO DATA TOKEN _C2 JSR TSTBRK ; IF BREAK BIT BNE _CDONE ; THEN DONE JSR GETCODE ; GET TOKEN _C1 CMP #CEOL ; IS IT EOL? BEQ _CDONE ; IF YES, WE'RE DONE CMP #CCOM ; IS IT COMMA? BNE _C4 ; IF NOT, DO CHANGE ; JSR UPCADR ; UPDATE CHANGE ADDR JMP _C2 ; _C4 ; JSR GETCODE ; GET DATA LOW LDY #0 ; STORE IN MEMORY STA (CSADR),Y ; X JSR GETCODE ; GET DATA HIGH BEQ _C2 ; IF =0 THEN REPEAT ; ; ; ; _CERR JSR VERROR ; DO ERROR HANDLING ; ; ; _CDONE UPCADR ; ; UPDATE CHANGE ADDR ; LDA CSADR ; INCR ADDR BY 1 CLC ; X ADC #1 ; X STA CSADR ; X LDA CSADR+1 ; X ADC #0 ; X STA CSADR+1 ; X ; RTS .PAGE 'EXECUTE EXIT' ; ; XX - RETURN TO EDITOR ; ?? RESET BREAK VECTOR ; XX LDA #EMODE ; RESET TO EDIT MODE STA MODEFLG ; X ; JMP ESYN2 ; GO TO EDITOR .PAGE 'EXECUTE GO' ; ; XG - EXECUTE GO ; XG JSR SETUPC ; SET PROGRAM COUNTER ; _GO ; ; SET UP TO HANDLE BREAK KEY ; BRKINIT LDY #.LOW.TPVBLK ; GET ROUTINE ADDR LOW LDX #.HIGH.TPVBLK ; GET ROUTINE ADDR HIGH LDA #7 ; JSR SETBVB ; SET ROUTINE ADDR TO USE AT VERT. BLANK ; ; SET UP BREAK VECTOR ; LDA #.LOW.VBRKG STA BRKVEC LDA #.HIGH.VBRKG STA BRKVEC+1 ; ; RESTORE REGISTERS ; LDY URY LDX URS TXS LDX URX LDA URP PHA LDA URA PLP ; JMP (UPC) .PAGE ; ; VERTICAL BLANK ROUTINE USED DURING GO ; - READS BREAK FLAG AND SIMULATE BREAK ; TPVBLK LDA BRKBYT ; BREAK KEY HIT? BEQ TPVB1 ; IF YES, GO SIMULATE BREAK JMP XITVBV ; ELSE EXIT VERT. BLANK ; ; SIMULATE BREAK (OS ROUTINE HAS PUT ADDR ON STACK) ; TPVB1 LDA #$80 ; SET BREAK KEY FLAG(KEY HAS BEEN READ) STA BRKBYT ; RESET DEF. VERT. BLANK FROM TEMPORARY JSR RSTVB ; TO NORMAL VECTOR TSX TXA CLC ADC #5 TAX LDA $100,X ; INCR PROGRAM COUNTER CLC ; UP TWO LOCATIONS TO SIMULATE BRK ADC #2 STA $100,X INX LDA $100,X ADC #0 STA $100,X PLA TAY ; RESTORE REGISTERS PLA TAX PLA PLP ; IRQ VECTOR FOR FINAL SYSTEMS PHP ; CHANGE TO JUMP ($216) FOR JMP ($FFFE) ; DEVELOPMENT SYSTEMS .PAGE 'EXECUTE STEP AND TRACE' ; ; XS - EXECUTE STEP ; XS JSR SETUPC ; GET PROGRAM COUNTER JSR STEP ; EXECUTE ONE INST. JMP DSYN2 ; RETURN TO DEBUG ; ; ; ; ; ; ; XT - EXECUTE TRACE ; XT JSR SETUPC ; GET PROGRAM VCOUNTER _TI JSR STEP ; EXECUTE ONE INST. JSR PRCR JSR TSTBRK ; IF BREAK WAS NOT HIT BEQ _TI ; THEN CONTINUE JMP DSYN2 ; RETURN TO DEBUG .PAGE ; ; STEP EXECUTE A SINGLE INST. ; ; ON ENTRY UPC - ADDR OF NEXT INST. ; STEP LDA #.LOW.VBRK ; SET BREAK VECTOR STA BRKVEC LDA #.HIGH.VBRK STA BRKVEC+1 PLA ; SAVE RETURN ADDR STA RTNADR ; X PLA ; X STA RTNADR+1 ; X CLD ; CLEAR DECIMAL MODE ; LDA UPC ; SET UP DISASSEMBLED ADDR STA LSADR ; X LDY UPC+1 ; X STY LSADR+1 ; X ; JSR DISASM ; DISASSEMBLE 1 INST. LDA STENUM ; WASTING AN INVALID INST CMP #CDUM BEQ RSTEP2 ; LDY #0 ; GET OP CODE LDA (UPC),Y ; X CMP #$4C ; IS IT JMP BEQ XJMP ; IF YES GO DO IT CMP #$6C ; IS IT IND JMP BEQ XIJMP ; IF YES, GO DO IT PHA ; SAVE OP CODE ASLA ; SHIFT OUT LEFT DIGIT ASLA ASLA ASLA BNE NOROP ; HANDLE NORMAL OP ; ; OTHER SPECIAL CASE OP CODES ; PLA ; GET OP CODE TAX ; SAVE FOR BR INST. LSRA ; GET LEFT DIGIT *2 LSRA LSRA TAY LDA SPTAB+1,Y ; GET ROUTINE ADDR PHA ; FOR SPECIAL OPS LDA SPTAB,Y PHA RTS ; GO DO IT .PAGE ; ; NORMAL OP CODES ; NOROP PLA NOROP1 JSR EXINIT ; INIT EXECUTION BUFFER LDY ILEN ; GET INST. LENGTH DEY _NOR LDA (UPC),Y ; MOVE INST TO EXBUFF STA (EXBUFF),Y ; X DEY BPL _NOR ; X ; _NOR2 LDY URY ; RESTORE USER REGS LDX URS TXS LDX URX LDA URP PHA LDA URA PLP JMP (EXBUFF) .PAGE RSTEP ; ; SAVE USERS REGISTERS ; STA URA ; SAVE A STX URX ; X STY URY ; SAVE Y PHP ; SAVE STATUS PLA STA URP RSTEP0 TSX ; SAVE STACK POINTERS STX URS ; ; UPDATE USER PC ; RSTEP2 LDA LSADR STA UPC LDA LSADR+1 STA UPC+1 ; RSTEP1 CLD ; CLEAR DECIML MODE JSR XDR ; PRINT USER REGS ; LDA RTNADR+1 PHA ; RETURN TO CALLER LDA RTNADR PHA RTS .PAGE ; ; SPECIAL CASE OPS CODES ; XJSR LDX URS ; GET USER'S STACK PTR TXS CLC ; PUT RETURN ADDR ON STACK LDA #2 ADC UPC TAX LDA #0 ADC UPC+1 PHA TXA PHA TSX STX URS ; SAVE NEW STACK PTR ; ; ;; ; XJMP JSR GJADR ; GET JUMP ADDR ; JMP RSTEP1 ; ; ; ; XIJMP JSR GJADR ; GET INDERICT ADDR LDY #0 JSR GJADR1 JMP RSTEP1 ; GO DO IT ; ; ; ; XRTI LDX URS ; GET USER'S STACK PTR TXS PLA ; GET STATUS FROM STACK STA URP TSX ; SET NEW STACK STX URS ; ; ; ; XRTS LDX URS ; GET USER'S STACK PTR TXS CLC ; PUT RETURN ADDR+1 PLA ; FROM STACK INTO ADC #1 ; USER PC STA UPC PLA TSX STX URS ; SET USER'S STACK PTR ADC #0 STA UPC+1 JMP RSTEP1 ; ; ; ; XBRK JMP (UPC) ; ; BRANCH INST. ; ; XBR JSR EXINIT ; INIT EXECUTION BUFFER TXA ; GET OP CODE LDY #0 ; PUT IN EXEC. BUFFER STA (EXBUFF),Y INY ; SET BR PASS DISPL LDA #4 ; X STA (EXBUFF),Y ; LDA #$4C ; SET UP FOR BR PASS LDY #06 STA (EXBUFF),Y LDA #.LOW.XBR1 INY STA (EXBUFF),Y LDA #.HIGH.XBR1 INY STA (EXBUFF),Y ; JMP _NOR2 ; ; XBR1 LDY #1 ; GET BR DISPL FROM LDA (UPC),Y ; USER'S CODE ; CLD JSR CREL ; CALC BR ADDR STA UPC+1 ; SET NEW ADDR STX UPC ; JMP RSTEP1 .PAGE ; ; EXINIT - INIT EXECUTION BUFFER ; EXINIT LDY #1 LDA #$EA ; PAD EXBUFF WITH NOP STA (EXBUFF),Y ; X INY STA (EXBUFF),Y INY LDA #$4C ; PUT IN RETURN JUMP STA (EXBUFF),Y INY LDA #.LOW.RSTEP STA (EXBUFF),Y LDA #.HIGH.RSTEP INY STA (EXBUFF),Y RTS .PAGE ; ; SETUPC - GET NEW PROGRAM COUNTER FROM COMMAND BUFFER ; SETUPC JSR GETCODE ; GET NEXT CODE CMP #CEOL ; IS IT END OF LINE BEQ _GPC ; IF YES, USE CURRENT PC JSR GETCODE ; ELSE, GET ADDR INTO PC STA UPC JSR GETCODE STA UPC+1 _GPC RTS ; ; ; ; ; GJADR - GET JUMP ADDRESS ; GJADR LDY #1 ; GET ADDR POINTED TO BY UPC GJADR1 LDA (UPC),Y TAX INY LDA (UPC),Y STA UPC+1 ; AND SAVE AS NEW UPC STX UPC RTS .PAGE ; ; SPTAB - ROUTINES FOR SPECIAL CASE OPS ; SPTAB .WORD XBRK-1 ; BRK .WORD XBR-1 ; BPL .WORD XJSR-1 ; JSR .WORD XBR-1 ; BMI .WORD XRTI-1 ; RTI .WORD XBR-1 ; BVC .WORD XRTS-1 ; RTS .WORD XBR-1 ; BVS *=*+2 .WORD XBR-1 ; BCC .WORD NOROP1-1 ; NORMAL OP .WORD XBR-1 ; BCS .WORD NOROP1-1 ; CPY # .WORD XBR-1 ; BNE .WORD NOROP1-1 ; NORMAL OP .WORD XBR-1 ; BEQ .PAGE ; ; VBRKG - BREAK VECTOR FOR SOFTWARE BREAK ; ; ENTERED HERE IF GET SOFTWARE BREAK OR ; HIT BREAK KEY DURING GO ; VBRKG STX URX ; SAVE X REGISTER BRKPAT STY URY ; SAVE X PLA ; GET A REGISTER PUSHED ON BY STA URA ; SOFTWARE INTERRUPT PLA ; GET STATUS CLI ; CLEAR INTERRUPT JUST IN CASE CLD ; CLEAR DECIAML STA URP ; SAVE STATUS JSR RSTVB ; RESTORE NORMAL BLANK RTN PLA ; GET PGM COUNTER FROM STACK SEC ; AND DECR BY 2 SO SBC #2 ; AS TO POINT TO START STA LSADR ; OF BRK INST. PLA ; X SBC #0 ; X STA LSADR+1 ; X LDA #.LOW.DSYN2-1 ; SET UP RTN ADDR STA RTNADR LDA #.HIGH.DSYN2-1 STA RTNADR+1 JSR PRPC ; PRINT THE USER PC JMP RSTEP0 ; AND JOIN WITH STEP ; ; ; ; RESET DEFERED VERTICAL BLANK ; RSTVB LDY #.LOW.XITVBV LDX #.HIGH.XITVBV LDA #7 JMP SETBVB .PAGE ; ; VBRK - BREAK VECTOR FOR SOFTWARE BREAK ; ; ENTER HERE IF GET SOFTWARE BREAK DURING ; STEP OR TRACE ; VBRK PLA ; REMOVE A REG PLA ; REMOVE STATUS AND RETURN ADDR PLA PLA CLD CLI JSR XDR JMP DSYN2 .PAGE 'EXECUTE VERIFY' ; ; XV - EXECUTE VERIFY' ; XV JSR TADR ; SET UP TO & FROM ADDR ; ; ; _V1 ; ; DO VERIFY ; JSR TSTBRK ;TEST FOR BREAK BNE _VEOF ; ; LDY #0 ; GET A BYTE LDA (MVTA),Y ; X STA LBUFF+1 ; SAVE IT ; JSR FAGET ; GET FROM BYTE BCS _VEOF ; BR IF AT END OF DATA ; CMP LBUFF+1 ; ARE THEY = ? BEQ _V2 ; IF YES, DON'T PRINT ; ; ; ; ; PRINT ADDR & DATA ; LDA MVFA ; PRINT FROM ADDR LDY MVFA+1 ; X JSR PRADRB ; X ; LDA LBUFF ; PRINT FROM DATA JSR PRHEXB ; X ; JSR PRBLK3 ; PRINT BLANKS ; LDA MVTA ; PRINT TO ADDR LDY MVTA+1 ; X JSR PRADRB ; X ; LDA LBUFF+1 ; PRINT TO DATA JSR PRHEXB ; X JSR PRCR ; PRINT CR ; _V2 JSR INCMVF ; INCR FROM ADDR ; _V3 INC MVTA ; INCR TO ADDR BNE _V1 ; X INC MVTA+1 ; X BNE _V1 ; REPEAT ; _VEOF RTS .PAGE 'EXECUTE MOVE' ; ; XM - EXECUTE MOVE ; XM JSR TADR ; SET UP TO & FROM ADDR ; ; DO MOVE ; _MOVE JSR TSTBRK ; IF BREAK HIT BNE _MEOF ; THEN END JSR FAGET2 ; GET BYTE FROM MEMORY BCS _MEOF ; BR IF END OF FILE ; ; DO PUT ; LDY #0 STA (MVTA),Y ; INC MVTA ; INCR TO ADDR BNE _MOVE ; X INC MVTA+1 ; X JMP _MOVE .PAGE ; ; TADR - GET TO ADDR & FROM ADR ; COX - POINTS TO 1ST BYTE OF # ; TADR JSR GETC1 ; GET ADDR FROM COMMAND STA MVTA ; & STORE AS TO ADDR JSR GETCODE ; X STA MVTA+1 ; X JSR GETC1 ; INCR INDEX ; ; ; ; ; ; FADR - GET FROM ADDR ; COX - POINTS TO 1ST BYTE OF # ; FADR JSR GETCODE ; GET ADDR FROM COMMAND STA MVFA ; & STORE AS FROM START ADDR JSR GETCODE ; X STA MVFA+1 ; X ; JSR GETC2 ; GET ADDR FROM COMMAND STA MVFEA ; AND STORE AS FROM END ADDR JSR GETCODE ; X STA MVFEA+1 ; X _MEOF RTS .PAGE ; ; FAGET - GET FROM ADDRS ; ; ; ON EXIT CARRY SET IF AT END OF FILE ; FAGET LDA MVFA+1 ; IF MOVE FROM END > CMP MVFEA+1 ; MOVE FROM THEN BCC _FA2 ; AT EOF BNE _FAFAIL ; X LDA MVFA ; X CMP MVFEA ; X BCC _FA2 ; X BNE _FAFAIL ; X ; ; _FA2 LDY #0 ; GET BYTE FROM MVFA LDA (MVFA),Y ; X STA (INBUFF),Y ; SAVE FROM BYTE IN BUFFER CLC _FAFAIL RTS ; ; ; ; ; FAGET2 - GET BYTE FROM ADDR + UPDATE ADDR ; FAGET2 JSR FAGET ; GET BYTE INCMVF INC MVFA ; INCR FROM ADDR BNE _FA3 INC MVFA+1 _FA3 RTS .PAGE ; ; GPCHAR - GET OR PUT CHARACTER ; ; ON ENTRY A - I/O TYPE ; X - DEVICE # ; LBUFF - PUT BYTE ; GPCHAR JSR GLPCX ; GET DEVICE INDEX & SET COMMAND ; LDY #1 ; GET BUFF LENGTH JSR IO3 ; SO I/O JMP IOTEST ; TEST I/O .PAGE 'EXECUTE DEBUG LIST - DISASSEMBLE' ; ; XL - LIST (DISASSEMBLE) ; XL ; ; SET DEFAULT ; (DEFAULT START ALREADY SET) ; LDA #20 ; SET # OF LINES TO LIST STA LNCNT ; X ; LDA #CNTON ; SET DISASSEMBLE CONTROL FLAG STA DISFLG ; TO CONTROL BY COUNT ; JSR GETCODE ; GET NEXT TOKEN CMP #CEOL ; AT END OF LINE BEQ _DL ; IF YES, SET UP DONE ; JSR GETCODE ; ELSE, GET START ADDR STA LSADR ; X JSR GETCODE ; X STA LSADR+1 ; X ; JSR GETCODE ; GET NEXT TOKEN CMP #CEOL ; BEQ _DL ; JSR GETC1 ; GET END ADDR STA LEADR JSR GETCODE STA LEADR+1 ; LDA #ADDRON ; SET DISASSEMBLE CONTROL FLAG STA DISFLG ; TO CONTROL BY ADDR ; ; CONTROL DISASSEMBLY ; _DL JSR TSTBRK ;TEST FOR BREAK BNE _DLDONE ; JSR DISASM ; GO DISASSEMBLE LINE ; LDA DISFLG ; GET CONTROL FLAG BEQ _CADR ; IFG = ADDR, TEST FOR END ADDR ; DEC LNCNT ; ELSE TEST FOR END COUNT BNE _DL ; IF NOT AT END, REPEAT RTS ; _CADR LDA LSADR+1 ; TEST FOR END OF ADDR RANGE CMP LEADR+1 BCC _DL ; IF NOT AT END, REPEAT BNE _DLDONE LDA LSADR CMP LEADR BCC _DL BEQ _DL _DLDONE RTS .PAGE 'DISASSEMBLER' ; ; DISASM - DISASSEMBLE ONE LINE ; DISASM JSR PRPC ; PRINT USER PC ; LDY #0 ; GET OP CODE LDA (LSADR),Y ; X STA STOP ; SAVE IT ; ; SEARCH FOR OP AS NON-MULTI ADDR ; LDA #.LOW.TOPTBL ; GET SEARCH ADDR LDY #.HIGH.TOPTBL LDX #EOP1 ; GET # BYTES TO SEARCH JSR OPSRCH ; SEARCH OP CODE BCC _DIS2 ; IF FOUND, BR LDX #TMULTI ; SET TYPE TO MULTI ADDR BNE _DIS3 _DIS2 CLC TYA ; ADJUST ENTRY # ADC #CSMNEM ; X STA STENUM LDX #0 JSR CLASF ; CLASSFY OP BY TYPE _DIS3 TXA JSR _DDUM ; ; RETURN HERE FROM SUBROUTINE ; STA ILEN ; SAVE LENGTH STX PMASK ; SAVE PRINT MASK ; ; PRINT OBJECT CODE ; STA ZT1 ; SAVE LENGTH AS COUNTER LDY #0 STY ZT2 ; SET INDEX _DIS4 LDY ZT2 LDA (LSADR),Y ; GET INST JSR PRHEXB INC ZT2 ; INCR INDEX DEC ZT1 ; DECT LENGTH COUNTER BNE _DIS4 ; IF MORE TO DO, BR ; .PAGE ; ; PRINT BLANKS FOR ALIGNMENT ; # = (3-ILEN)*3+4 ; SEC LDA #3 SBC ILEN STA ZT1 ASLA CLC ADC ZT1 CLC ADC #4 JSR PRBLANK3 ; GO PRINT THEM ; ; FIND MNEMONIC ; LDA STENUM ; ADJUST ENTRY # TO SEC ; COUNT JUST OPS SBC #CSMNEM ;X STA ZT1 ; LDY #.LOW.KWTAB2 LDA #.HIGH.KWTAB2 ; GET START OF TABLE ; _SCAN1 STA SRCADR+1 ; SET SCAN ADDR STY SRCADR LDY #$FF DEC ZT1 BMI _FMN ; _SCAN2 INY LDA (SRCADR),Y ; GET CHAR OF MNEMONIC BPL _SCAN2 ; INY JSR INCSRC ; INCR SEARCH ADDR BNE _SCAN1 ; BR ALWAYS .PAGE ; ; ; ; PRINT MNEMONIC ; _FMN LDY #0 ; SET UP INDEX STY ZT1 ; _MPR LDY ZT1 ; GET INDEX LDA (SRCADR),Y ; GET CHAR OF MNEMIC PHA AND #$7F ; TURN OFF HIGH ORDRER BIT, IF ON JSR PRCHAR ; PRINT CHAR INC ZT1 PLA BPL _MPR JSR PRBLK3 ; PRINT 3 BLANKS ; ; PRINT ADDRESS OPERAND ; LDA PMASK ; GET PRINT MASK BEQ PRA ; HANDLE ACU BMI PRREL ; HANDLE REL ADDR ; ASLA ; SHIFT 1ST MASK BIT TO MSB BMI _DISEND ; BR IF 1 BYTE INST ASLA STA PMASK ; LDY #6 ; SET 6 POSSIBLE COMBOS STY PRCNT _APR1 DEC PRCNT BMI _DISEND LDY PRCNT CPY #2 ;AFTER 3 TRIES, GO PRINT ADDR BEQ PRADR _APR2 LDA PMASK ;TEST NEXT BIT ASLA STA PMASK BCC _APR1 ;IF OFF, NO PRINT ; ; ELSE PRINT THE CHARS CORRESPONDING TO BIT ; LDA STR1,Y ;GET CHAR FROM STRING 1 JSR PRCHAR LDY PRCNT ; GET INDEX AGAIN LDA STR2,Y ;PRINT CHAR FROM STRING 2 BEQ _APR1 JSR PRCHAR JMP _APR1 PRA LDA #'A ; PRINT CHAR A JSR PRCHAR ; _DISEND JSR INCLA ; INCR LIST ADDRESS JMP PRCR ; PRINT CARRIDGE RETURN ; ; ; ; ; ; PRINT ADDR FOR BRANCH ; PRREL LDA #'$ JSR PRCHAR ; LDY #1 ; GET RELATIVE DISPL LDA (LSADR),Y ; X PHA ; SAVE JSR INCLA ; INC LIST ADDR PLA JSR CREL ; CALC RELATIVE BR ADDR _PRR TAY ; GO PRINT TXA ; X JSR PRHEX2 ; X JMP PRCR ; PRINT CR .PAGE ; ; PRINT THE ADDR OR DATA ; PRADR LDA (LSADR),Y ; X TAX ; X DEY ; X LDA (LSADR),Y ; X ; LDY ILEN ; GET INST LENGTH CPY #3 ; IF INSTR LENGTH NOT = 3 BNE _PRAD1 ; GO PRINT 1 BYTE PHA ; ELSE PRINT 2 BYTE TXA JSR PRIHEX PLA _PRAD1 JSR PRIHEX LDY #2 ; BNE _APR2 .PAGE ; ; PRINT USER PC ; PRPC LDA LSADR ; PRINT DISASSEMBLE ADDR LDY LSADR+1 ; X JSR PRADRB ; X JSR PRBLK3 ; X RTS .PAGE ; ; ; ; INCLA - INCREMENT LIST ADDRESS BY ILEN ; INCLA CLC LDA LSADR ; INCR LIST ADDR ADC ILEN STA LSADR ; X LDA LSADR+1 ; X ADC #0 ; X STA LSADR+1 ; X RTS ; ; ; ; ; CRCL - CALCULATE RELATIVE BRANCH ADDR ; ; ON ENTRY A - DISPL ; ON EXIT A - ADDR HIGH ; X - ADDR LOW ; CREL BMI _BBACK ; IF MINUS, BR BACK CLC ; ELSE CALC ADDR FOR ADC LSADR ; FORWARD BR TAX ; X LDA #0 ; X ADC LSADR+1 ; X RTS _BBACK EOR #$FF ; TAKE COMPLIMENT OF DISPL CLC ADC #1 ; X SEC ; CALC BACKWARD BR STA ZT1 LDA LSADR ; X SBC ZT1 TAX LDA LSADR+1 ; X SBC #0 ; X RTS .PAGE _DDUM ASLA ; GET ROUTINE ADDR TAY ; BY INST TYPE LDA ITTAB-3,Y ; X PHA LDA ITTAB-4,Y PHA RTS ; X ; ; ; ; ; ; ITTAB - ROUTINE ADDR BY INSTRUCTION TYPE ; ITTAB .WORD DIMP-1 ; IMPLIED .WORD DREL-1 ; RELATIVE .WORD DMISC-1 ; MISCELLANEOUS .WORD DMULTI-1 ; MULTI - ADDRESS .PAGE 'DISASM IMPLIED, RELATIVE & MISC' ; ; DIMP - DISASSEMBLE IMPLIED INST ; DIMP LDA #1 ; GET INSTR LENGTH LDX #$40 ; GET PRINT TYPE FROM ADDR RTS ; ; ; ; ; DREL - DISASSEMBLE RELATIVE INSTRUCTION ; DREL LDA #2 ; SET INST LENGTH LDX #$80 ; GET PRINT TYPE RTS ; ; ; ; ; DMISC - DISASSEMBLE MISCELLANEOUS INST. ; DMISC LDA #3 LDX #PABS.AND.$3F RTS .PAGE 'DISASSEMBLE MULTI-ADDRESS INSTRUCTION' ; ; DMULT ; DMULTI LDA STOP ; GET OP PHA ; SAVE IT CMP #$6C ; IT IS JMP INDERECT BEQ _SIJMP ; GO SET UP FOR JUMP IND ; AND #$E3 ; OR OUT ADDR BITS STA STOP ; SAVE FOR SEARCH ; LDA #.LOW.TOPT2 ; GET SEARCH ADDR LDY #.HIGH.TOPT2 LDX #EOP2 ; GET # BYTES TO SEARCH JSR OPSRCH ; GO SEARCH BCS _NF ; BR IF NOT FOUND ; CLC TYA ; ADJUST ENTRY # ADC #CSMULT ; X STA STENUM ; X PLA ; RESTORE OP ; ; CHECK FOR INVALID OP ; LDY #NOINV ; GET # OF ENTRIES IN INVALID OP TABLE _DM2 CMP INVOPT,Y ; IS OUR CODE INVALID BEQ _NF1 ; IF YES, BR DEY ; ELSE CHECK NEXT ONE BPL _DM2 ; AND #$1F ; GET ADDR TYPE INDEX TAY LDA PMTAB,Y ; GET PRINT MASK & LEN BEQ _NF1 ; IF MASK = 0 THEN INVALID OP TAY ; SAVE AND #$3F ; GET PRINT MASK TAX TYA AND #$C0 ; GET LENGTH LSRA LSRA LSRA LSRA LSRA LSRA ; ; SPECIAL CASE STX & LDX ; TAY ; SAVE IN Y LDA STOP ; GET TRIAL OP AND #$DF CMP #$82 ; IS IT LDX OR STX? BNE _DM1 ; CPX #PABSX.AND.$3F BNE _DM1 LDX #PABSY.AND.$3F _DM1 TYA ; RECOVER LENGTH RTS _NF PLA ; FIX STACK _NF1 LDA #CDUM ; STA STENUM ; SET NOT FOUND LDA #1 ; GET LENGTH LDX #$40 RTS ; ; _SIJMP PLA ; CLEAR STACK LDA #CJMP ; POINT TO JMP MNEMONICS STA STENUM ; X LDX #$12 ; GET PRINT MASK LDA #3 ; GET LENGTH RTS .PAGE ; ; INVOPT - INVALID OP CODE TABLE ; INVOPT .BYTE $02 .BYTE $22 .BYTE $34 .BYTE $3C .BYTE $42 .BYTE $62 .BYTE $82 .BYTE $89 .BYTE $9C .BYTE $80 .BYTE $9E .BYTE $C2 .BYTE $D4 .BYTE $DC .BYTE $F4 .BYTE $FC .BYTE $E2 NOINV = *-INVOPT-1 .PAGE 'SEARCH OP CODE TABLE' ; ; OPSRCH - SEARCH OP CODE TABLE ; ; A - SEARCH ADDR LOW ; Y - SEARCH ADDR HIGH ; X - # BYTES TO LOOK AT ; ; ON EXIT Y - ENTRY # ; OPSRCH STX SRCCNT ;SAVE # BYTE TO SEARCH STA SRCADR ; SAVE TABLE ADDR STY SRCADR+1 ; X ; LDY #0 LDA STOP _OPS1 CMP (SRCADR),Y ; GET TABLE ENTRY BEQ _OPF ; INY ; INCR INDEX CPY SRCCNT ;IF MORE TO SEARCH BCC _OPS1 ; DO IT ; SEC RTS _OPF CLC RTS .PAGE ; ; PRINT MASK EQUATES ; ; LOW ORDER 6 BITS = MASK ; HIGH ORDER 2 BITS = LENGTH ; LONE = $40 LTWO = $80 LTHREE = $C0 ; ; PIMM = $20+(.LOW.LTWO) PINDX = $16+(.LOW.LTWO) PINDY = $13+(.LOW.LTWO) PZPG = $08+(.LOW.LTWO) PZPGX = $0C+(.LOW.LTWO) PZPGY = $09+(.LOW.LTWO) PABS = $08+(.LOW.LTHREE) PABSX = $0C+(.LOW.LTHREE) PABSY = $09+(.LOW.LTHREE) PACU = 0+(.LOW.LONE) ; ; ; ; ; PRINT CHARACTER STRING ; STR1 .BYTE ',),$(#' STR2 .BYTE 'Y',0,'X',0,'$','$' .PAGE ; ; PMTAB - PRINT CONTROL MASK TABLE ; PMTAB .BYTE PIMM ; IMM 0 .BYTE PINDX ; INDX 1 .BYTE PIMM ; IMM 2 .BYTE 0 ; - 3 .BYTE PZPG ; ZPG 4 .BYTE PZPG ; ZPG 5 .BYTE PZPG ; ZPG 6 .BYTE 0 ; - 7 .BYTE 0 ; - 8 .BYTE PIMM ; IMM 9 .BYTE PACU ; ACU 10 .BYTE 0 ; - 11 .BYTE PABS ;ABS 12 .BYTE PABS ;ABS 13 .BYTE PABS ;ABS 14 .BYTE 0 ; - 15 .BYTE 0 ; - 16 .BYTE PINDY ; INDY 17 .BYTE 0 ; - 18 .BYTE 0 ; - 19 .BYTE PZPGX ; ZPGX 20 .BYTE PZPGX ; ZPGX 21 .BYTE PZPGX ; ZPGX 22 .BYTE 0 ; - 23 .BYTE 0 ; - 24 .BYTE PABSY ; ABSY 25 .BYTE 0 ; - 26 .BYTE 0 ; - 27 .BYTE PABSX ; ABSX 28 .BYTE PABSX ; ABSX 29 .BYTE PABSX ; ABSX 30 .PAGE 'EXECUTE MINI-ASSEMBLER' ; ; XA - EXECUTE MINI-ASSEMBLER ; XA ; JSR AINIT ; GO INIT FOR MINI-ASSEMBLER ; LDA #PASS2 ; SET PASS 2 FLAG STA PASSFLG ; X ; LDA #MAMODE ; SET MODE FLAG STA MODEFLG ; X MASYNTAX LDX #$FF ;RESET STACK POINTER TXS ; X JSR SYNINIT ; GO GENERASL SYNTAX INIT BNE MASYNTAX ; BR IF BREAK ; JSR SKPBLK JSR GETIN ; GET INPUT CHAR CMP #DELIM ; IS IT DELIMETER BEQ _MINI ; IF YES, USE CURRENT LOCATION COUNTER CMP #CR ; IF CR THAN DONE BEQ _MINI2 ; DEC CIX ; BACK UP TO 1ST DIGIT ; JSR GETHEX ; GET HEX # BCS _MASER ; JSR SKPBLK JSR GETIN ; GET INPUT CHAR CMP #DELIM ; X BNE _MASER ; LDY COX ; GET OUTPUT INDEX CPY #3 ; SHOULD HAVE BEEN 2 BYTES BNE _MASER ; IF NOT, ERROR DEY LDA (OUTBUFF),Y ; PUT ADDR IN LOC COUNTER STA LOCCNT+1 ; X DEY ; X LDA (OUTBUFF),Y ; X STA LOCCNT ; X LDA #0 ; RESET OUTPUT INDEX STA COX ; X _MINI JSR ASM1A ; GO ASSEMBLE LINE BCS MASYNTAX ;IF ERROR, GET NEW LINE LDA EOFFLG ; ARE WE AT EOF (.END)? BPL MASYNTAX ; IF NOT CONTINUE ; _MINI2 JSR ARESET ; DO REST JMP BUG1 ; RETURN TO DEBUG ; ; _MASER LDA #ERMSYN JSR ERROR _MASE1 JSR PRTERR ; PRINT ERROR JMP MASYNTAX .PAGE 'EXECUTE ASM' ; LOCAL ; ; XASM - EXECUTE ASM ; XASM ; JSR AINIT ; GO INIT COMMON TO MINI-ASM ; LDA TXTTAB ; POINT TO FIRST LINE IN TEXT STA STMCUR ; X LDA TXTTAB+1 ; X STA STMCUR+1 ; X ; LDA #AMODE ; SET ASM MODE STA MODEFLG ; X LDA #PASS1 ; SET PASS FLAG TO PASS 1 STA PASSFLG ; ; PROCESS PARMS ; JSR GETCODE ; GET TOKEN CMP #CEOL ; IS IT EOL? BEQ _PDONE ; IF YES, PARMS DONE CMP #CCOM ; IS IT COMMA? BEQ _PARM2 ; IF YES, USE PARM 1 DEFAULT ; ; SET UP SOURCE FILE ; ; JSR FLOAD ; OPEN ENTRY FILE LDA #NTCMD ; DO NOTE FOR SECOND PASS LDX ENTDTD JSR GLPCX JSR IO7 JSR IOTEST ; LDX ENTDTD ; SAVE NOTE VALUES JSR LDDVX LDA ICAUX3,X STA TEMPRL LDA ICAUX4,X STA TEMPRL+1 JSR GETCODE ; GET CODE CMP #CEOL ; IS IT EOL? BEQ _PDONE ; IF YES, WE ARE DONE ; _PARM2 JSR GETCODE ; GET TOKEN CMP #CCOM ; IS IT COMMA? BEQ _PARM3 ; IF YES, USE PARM 2 DEFAULT ; JSR FLIST ; OPEN LIST FILE JSR GETCODE ; GET CODE CMP #CEOL ; IS IT EOL? BEQ _PDONE ; IF YES, WE ARE DONE _PARM3 JSR GETCODE ; GET TOKEN ; ; SET UP OBJECT FIELD ; ; LDX #OBJDV STX OBJDTD ; SETUP FOR OBJECT FILE JSR _LEOF1 JSR STRMOV ; ; _PDONE ASM3 JSR TSTBRK ;IF BREAK BNE _ABRK ; THEN DONE ; JSR ASM1L ; ASSEMBLE 1 LINE ; LDA EOFFLG ; GET EOF FLG BPL ASM3 ; IF NOT EOL, DO NEXT LINE ; ASL PASSFLG ; TEST FOR PASS 2 BNE _ADONE ; IF PASS 2 BIT ON, BR LDA #PASS2 ; ELSE SET PASS 2 STA PASSFLG ; X LDX #TITLEP+2 ; CONTRACT TITLE & PAGE BUFFER LDY SMBLD+1 LDA SMBLD JSR CLR1 JSR AINIT2 ; INIT FOR PASS 2 JSR TOP3 LDA OBJDTD BEQ ASM3 ; NO OBJECT FILE ; AT START OF SECOND PASS, WE OPEN OBJECT FILE ; STA IODVC LDA #8 JSR OP2 ; OPEN, PHASE 2 ; LDA #LCHK1 TAX JSR HPUTO2 ; HEADER BYTES JMP ASM3 ; TO SECOND PASS _ADONE LDA ERRCNT ; HOW MANY ERRORS? BPL _ADN2 ; SOME LDA #'> ; TOO MANY JSR PRCHAR LDA #127 ; MAX WE CAN CNT _ADN2 JSR PRNUMA LDX #.LOW.CNTMSG LDY #.HIGH.CNTMSG JSR MSGXYCR ; ABRK = * _ABRK JSR CLSALL ; CLOSE ALL DEVICES ASMR JSR ARES1 ; DO RESET JMP ESYN2 ; RETURN TO EDITOR CNTMSG .BYTE ' ERROR',$80+'S' .PAGE ; ; ASM1L - ASSEMBLE ONE LINE ; ASM1L JSR GASML ; GET AN INPUT LINE BCS XEND2 ; IF AT END OF FILL, BR ; ASM1A LDA #0 STA IDISPL ; CLEAR PRINT DISPL STA ADISPL ; X STA COX ; INIT OUTPUT INDEX ; JSR ASYNTAX ; SYNTAX LINE BCS LSYNER ; IF ERROR, LIST LINE ; ; PROCESS TOKEN ; LDY #0 STY OBJDEX ; ZERO OBJECT INDEX LDY #3 ; SET OUTPUT DEVICE STY COX ; X JSR GETCODE ;GET TYPE OF STATEMENT ; JSR _ADUM ; ; RETURN HERE FROM SUBROUTINE ; OUT STA OLBCNT ;STORE NUMBER BYTES PER LINE JSR OCNTL ; TAKE CARE OF ALL OUTPUT CLC RTS ; ; LSYNER LDA MODEFLG ; GET MODEFLAG CMP #MAMODE ; ARE WE IN MINI-ASM? BEQ _ASYNER AXCOM ; ENTRY POINT FOR COMMAND LISTING JSR TSTLIST ; DO WE LIST? BNE _ASDONE ; IF NOT, BR JSR TSTEJT ; TEST FOR PAGE EJECT LDA #PLST ;INDENT LINE LIST JSR PRBLANKS ;X JSR INBOUT _ASYNER JSR TSTOERR ;PRINT ERROR IF REQUIRED _ASDONE SEC RTS .PAGE _ADUM ASLA ; GO PROCESS TOKEN BY TYPE TAY ; X LDA AXTBL+1,Y ; X PHA ; X LDA AXTBL,Y ; X PHA RTS .PAGE ; ; AXDIR - EXECUTE DIRECTIVES ; AXDIR JSR GETCODE ; GET TYPE OF DIRECTIVE ; ASLA ; GO TO PROPER ROUTINE TAY LDA ADXTBL-CSDIR-CSDIR+1,Y PHA LDA ADXTBL-CSDIR-CSDIR,Y PHA RTS .PAGE 'EXECUTE DIRECTIVE' ; ; XEND- EXECUTE END DIRECTIVE ; XEND LDA ENTDTD ; GET INPUT DEVICE BNE _END ; IF NOT = MEMORY, BR XEND2 JSR PORG ; PROCESS LAST ORG LDA #$80 ; ELSE SET END A FILE STA EOFFLG LDA #0 ; GET # OF BYTES OF OBJECT _END CLC RTS .PAGE 'EXECUTE IF DIRECTIVE' ; ; XIF - EXECUTE IF DIRECTIVE ; XIF JSR XEXP ; EVALUATE EXP BNE _IF1 ; IF EXP NON-ZERO TAX ; THEN SKIP SOME USER CODE BNE _IF1 ; ELSE RETURN ; LDA RESBYT ; GET RESOLVE BYTE LSRA ; IF UNRESOLVED, TREAT AS BCS _IF1 ; NON-ZERO RTS ; _IF1 LDA #0 ; PRINT IF LINE JSR OUT JSR GETC3 ; POINT TO START OF STRING STA SVLENG ; SAVE LENGTH LDY COX ; SAVE START OF STRING STY TSCOX ; X ; ; SEARCH FOR LABEL IN CODE TO MATCH .LABEL IN IF ; _IF2 JSR GASML ; GET A LINE BCS _IF4 ; BR IF END OF FILE LDA CIX ; SAVE CIX STA SVCIX ; X LDX SVLENG ; GET STRLENG AS # OF BYTES TO SEARCH _IF3 DEX ; DEC COUNTER BMI _IFP ; IF AT END, POSSIBLE PASS JSR GETCODE ; GET .LABEL CHAR LDY CIX ; GET INPUT INDEX INC CIX CMP (INBUFF),Y BEQ _IF3 _IFF JSR AXCOM ; PRINT LINE LDA TSCOX ; RESTORE OUTPUT INDEX STA COX ; X BNE _IF2 ; BR ; ; .LABEL MATCHES LABEL (CHECK FOR END OF LABEL ; _IFP JSR TSTALPHA ; IF NOT AT END OF LABEL BCC _IFF ; THEN .LABEL NOT FOUND JSR TSTNUM ; X BCC _IFF ; X ; LDA SVCIX ; RESTORE CIX FOR THIS LINE STA CIX ; X ; ; PLA ; PULL RETURN ADDR PLA ; FROM STACK JMP ASM1A ; ASM THE LINE ; _IF4 PLA ; PULL RETURN ADDR PLA JMP XEND2 ; HANDLE LIKE END .PAGE ; ; GASML - GET NEXT ASM LINE ; GASML JSR INTLBF ; INIT INBUFF LDA ENTDTD ; GET INPUT DEVICE BEQ _GLTXT ; IF = MEMORY GET LINE FROM TABLE ; ; GET LINE FROM DEVICE ; JSR GLGO CMP #$88 ; ARE WE AT EOF? BNE ASM1B RTS _GLTXT JSR TSTTEND ; TEST FOR END OF TEXT BCS ASM1D ; BR IF AT END OF TEXT ; ; LDA #0 STA LTYPFLG ;SET TO LIST LINE # ; ; MOVE THE LINE ; JSR MOVLIN ; LIST LINE TO BUFFER JSR GETLL ; GET NEXT STATEMENT JSR GNXTL ; X ASM1B ; ; CHANGE TABS TO BLANKS ; LDY #127 ; GET BUFFER LENGTH TSTTC LDA (INBUFF),Y ; GET A CHARACTER FROM BUFFER CMP #TC ; IS IT TAB? BNE NOTTAB ; IF NOT BR LDA #$20 ; STA (INBUFF),Y ; IF YES REPLACE WITH BLANKX NOTTAB DEY ; DEC TO NEXT CHAR IN BUFFER BPL TSTTC ; IF NOT DONE, BR ; LDA #0 STA CIX ; INIT INPUT INDEX JSR CVAFP ; SKIP LINE # BCS ASM1C ; IF ERROR BR INC CIX ; INCR PAST BLANK ASM1D RTS ; ASM1C LDA #ERGARB JSR ERROR JSR PRTERR SEC RTS .PAGE 'EXECUTE TITLE DIRECTIVE' ; ; XTITLE - EXECUTE TITLE DIRECTIVE ; XTITLE ; LDX #TITLEP ; SET FOR TITLE BUFFER ; ; ; MOVE STRING FROM PAGE & TITLE ; (X CONTAINS POINTER TO TITLE OR PAGE BUFFER ADDR) ; PTSTR JSR GETCODE ; GET NEXT CODE CMP #CEOL ; ARE WE AT END BEQ _PTDONE ; IF YES, DONE ; LDA 0,X ; GET BUFFER ADDR (TITLE OR PAGE) STA PTBUFF ; X LDA 1,X ; X STA PTBUFF+1 ; X ; JSR GETC1 ; GET STRING LENGTH PHA ; SAVE IT SEC ; SUBTRACT CURRENT BUFFER LENGTH LDY #0 ; TO GET # OF BYTES TO SBC (PTBUFF),Y ; EXPAND OR CONTRACT (NEW - OLD) BEQ _PTMOV ; BR NEW = OLD BCS _PTEXP ; BR NEW > OLD (EXPAND) ; ELSE NEW < OLD (CONTRACT) EOR #$FF ; COMPLIMENT TO GET +# OF BYTES TAY ; X INY ; X INX ; POINT TO END OF CONTRACT AREA INX ; JSR CONTLOW ; GO CONTRACT JMP _PTMOV _PTEXP TAY ; PUT # OF BYTES IN Y INX ; POINT TO EXPAND POINT INX JSR EXPLOW ; GO EXPAND ; _PTMOV PLA ; GET STRING LENGTH TAX ; SAVE AS LOOP CONTROL LDY #0 ; SET INDEX INTO BUFFER STY PTDEX ; X _PT2 STA (PTBUFF),Y ; PUT LENGTH IN BUFFER JSR GETCODE ; GET STRING CHAR INC PTDEX ; INCR BUFFER POINTER LDY PTDEX ; GET INDEX DEX ; DEC COUNTER BNE _PT2 ; BR IF MORE TO DO ; ORA #$80 ; STA (PTBUFF),Y _PTDONE LDA #0 ; GET # OF BYTES OF ZERO RTS .PAGE 'EXECUTE PAGE DIRECTIVE' ; ; XPAGE - EXECUTE PAGE DIRECTIVE ; XPAGE LDX #PAGEP ; POINT TO PAGE BUFFER JSR PTSTR ; MOVE STRING ; PAGE1 JSR TSTLIST ; TEST FOR LISTING BNE _PTPR1 ; IF NO LIST THAN BR LDA LINESPERPAGE SEC SBC LNCNT ; GETS # OF LINES LEFT LDX FFOK ; OK TO DO FORM FEED? BEQ PG1NOFF ; NO ; LDA #PEJECT ; YES JSR PRCHAR ; FF JMP TOP3 ; PG1NOFF CLC ADC #4 ; 4 LINES AT TOP OF PG STA LNCNT PG1LP JSR PRCR ; BLANK LINE DEC LNCNT ; MORE? BNE PG1LP ; YES ; NO MORE...AND LNCNT=0 ; TOP3 LDA #0 STA LNCNT ; JSR PRTITLE ; PRINT TITLE JSR PRPAGE ; PRINT PAGE JSR PRCR ; PUT OUT EXTRA CR _PTPR1 RTS .PAGE ; ; PRPAGE - PRINT PAGE ; ; PRTITLE - PRINT TITLE ; PRTITLE LDX TITLEP ; GET ADDR LOW LDY TITLEP+1 ; GET ADDR HIGH BNE _PTPR ; PRPAGE LDX PAGEP ; GET ADDR LOW LDY PAGEP+1 ; GET ADDR HIGH ; _PTPR INX ; INCR LOW ORDER BYTE BNE _PT ; INY ; IF ZERO, INCR ADDR HIGH _PT JMP MSGXYCR ; PRINT .PAGE 'EXECUTE WORD & DBYTE' ; ; XDBYTE - EXECUTE DBYTE ; ; XWORD - EXECUTE DWORD ; ; ; XDBYTE LDA #DBYTEON ; SET FLAG FOR DBYTE BNE _WORD ; XWORD LDA #WORDON ; SET FLAG FOR WORD _WORD STA WORDFLG ; STORE FLAG ; _WORD2 JSR XEXP ; GET VALUE OF EXPRESSION ; LDY WORDFLG ; GET FLAG BEQ _WORD3 ; IF SET FOR WORD, OUTPUT NON-REVERSE ; TXA ; ELSE OUTPUT IN REVERSE ORDER LDX FR0 ; X _WORD3 JSR OBJM2 ; PUT OUT 2 BYTE OBJECT ; JSR GETCODE ; GET CODE CMP #CCOM ; IS IT COMMA? BEQ _WORD2 ; IF YES, DO NEXT INTEM LDA #TWOBYTE ; GET 2 BYTES OBJECT PER PRINT LINE RTS .PAGE 'EXECUTE BYTE' ; ; XBYTE - EXECUTE BYTE ; XBYTE JSR GETCODE ; GET TOKEN AND #$7F ; OR OUT MSB IF ON CMP #THEX2 ; IS THIS A #? BEQ _BYT1 ; IF YES, OUTPUT VALUE OF EXP ; ELSE IT IS A STRING ; JSR GETC1 ; GET LENGTH TAX ; USE AS COUNTER BEQ _BERR1 _BYT2 L JSR GETCODE ; GET STRING CHAR JSR OBJMAN ; PUT IN OBJECT BUFFER DEX BNE _BYT2 ; REPEAT IF MORE STRING CHAR BEQ _BYT3 ; _BYT1 DEC COX ; BACK UP TO # CODE FOR EXECUTE EXPRESSION JSR XEXP ; EVALUATE EXPRESSION JSR BIT8 ; TEST FOR 8 BIT VALUE JSR OBJMAN ; PUT IN OBJECT BUFFER ; _BYT3 JSR GETCODE ; GET NEXT CODE CMP #CCOM ; IS IT COMMA? BEQ XBYTE ; IF YES,THEN PROCESS NEXT ITEM ; LDA #ONEBYT ; GET 1 BYTE OBJECT PER LINE RTS ; _BERR1 LDA #ERNSTR JSR ERROR RTS .PAGE 'EXECUTE TAB DIRECTIVE' ; ; XTAB - EXECUTE TAB ; XTAB LDA #0 ; GET TAB DISPL = 0 STA TABCNT ; X _TAB JSR XEXP ; EVALULATE EXPRESSION CLC ADC #PLST ; ADD DISPL TO INPUT POINT LDX TABCNT ; X STA TAB1,X ; X INC COX ; INCR OVER COMMA INX ; POINT TO NEXT TAB CPX #3 ; X STX TABCNT ; X BCC _TAB ; BR IF HAVE NOT DONE 3 LDA #0 ; GET # OF BYTES OF OBJECT RTS .PAGE 'ORG DIRECTIVE' ; ; XORG ; ; ON PASS 1 AN ENTRY IS CREATED FOR EACH ORG IN THE LABEL ; TABLE WITH A LABEL OF ; ; ; ON PASS 2 THE NEXT LABEL FOR THE NEXT ORG IN TABLE IS CHANGED TO * ; ; THIS IS DONE SO WE CAN KNOW START & END ADDRESS ; OF THIS SECTION OF OBJECT FOR THE OBJECT FILE ; ; XORG LDA LOCCNT ; MOVE LOCATION COUNTER STA MVFA LDA LOCCNT+1 STA MVFA+1 ; JSR XEXP ; EVALUATE EXPRESSION ; TAY ;SAVE VALUE LOW LDA RESBYT ;GET RESOLVE BYTE LSRA ;TEST UNRESOLVED BIT BCC _ORG ;IF NOT ON, VALUE OKAY ; LDA #ERUFR ;ELSE ERROR JSR ERROR ; JSR PRTERR JMP _ABRK ; ABORT ; _ORG LDA OPTFLG ; IF OBJ OPT=NO AND #OOBJ ; THEN DON'T PROCESS ORG AS LABEL BNE _ORGA JSR PORG ; PROCESS PREVIOUS ORG ; JSR DOORG ; HANDLE THIS ORG _ORGA LDA FR0 ; SET LOCATION COUNTER TO NEW ORG VALUE STA LOCCNT LDA FR0+1 STA LOCCNT+1 LDA MVFA ; PUT OLD LOCATION IN FR0 STA FR0 LDA MVFA+1 ; X STA FR0+1 ; X JMP _SPPRT ; DO SPECIAL PRINT OF THIS LINE ; ; ; ; ; DOORG - HANDLE LABEL TABLE LOOK-UP ; ; ON ENTRY - ORG VALUE IS IN FR0 ; DOORG LDA PASSFLG ; GET PASS FLAG BPL _OP2 ; BR IF PASS 2 ; LDA #'; ; ADD ENTRY TO LABEL TABEL LDY #'* JSR OSRCH ; LDA SRCADR ; SET CURRENT ORG PTR STA COPTR ; X LDA SRCADR+1 STA COPTR+1 ; X RTS ; ;; _OP2 LDA #'* ; SEARCH FOR NEXT ORG LDY #'; JSR OSRCH ; ; ; LDX OBJDTD ; GET OBJECT DEVICE BNE _ORGB ; IF = FILE THEN BR RTS ; ; ; PUT OUT OBJECT FILE HEADER ; _ORGB LDY #0 SEC LDA (SRCADR),Y SBC FR0 INY LDA (SRCADR),Y SBC FR0+1 BCC _OD ; BRANCH TAKEN => BAD ASSY LDX FR0 ; GET NEW ORG VALUE LDA FR0+1 ; JSR HPUTO2 ; CONDITIONAL : START ADDR ; LDY #0 ; GET END OF THIS ORG LDA (SRCADR),Y ; TAX INY LDA (SRCADR),Y JSR HPUTO2 ; CONDITIONAL : END ADDR _OD RTS .PAGE ; ; PORG - PROCESS PREVIOUS ORG ; ; ; SET CURRENT LOCATION COUNTER -1 AS ADDR IN ; LABEL TABLE FOR LAST ORG ENTRY ; PORG LDA COPTR ; IF = 0 THIS IS 1ST ORG OR PASS 2 ORA COPTR+1 ; SO BR BEQ _PO LDY #0 ; SET CURRENT LOC-1 SEC LDA LOCCNT ; IN ORG LABEL TABEL SBC #1 STA (COPTR),Y ; ENTRY INY LDA LOCCNT+1 ; X SBC #0 STA (COPTR),Y ; X _PO RTS .PAGE ; ; OSRCH - SEARCH FOR ORG ; ; SEARCH FOR CHARACTER GIVEN IN Y. IF NOT FOUND, IT IS CREATED ; THE FOUND CHARACTER IS THEN CHANGET TO THE CHARACTER ; IN A ; ; ON ENTRY A - CHANGE CHAR (* OR ;) ; Y - SEARCH CHAR ; OSRCH PHA ; SAVE CHANGE CHAR TYA ; GET SEARCH CHAR ; LDY #0 STY CIX TAX ; SAVE SEARCH CHAR LDA (INBUFF),Y ; GET CHAR FROM BUFFER PHA ; SAVE IT TXA ; GET SEARCH CHAR STA (INBUFF),Y ; SET SEARCH CHAR IN BUFFER INY STY TVSCIX ; SET UP FOR SEARCH JSR LBLS1 ; SEARCH LDY #0 ; RESTORE BUFFER CHAR PLA STA (INBUFF),Y LDY #3 ; CHANGE CHAR PLA ; GET CHANGE CHAR ORA #$80 ; OR IN MSB TO SET END OF STRING STA (SRCADR),Y RTS .PAGE 'EXECUTE EQU DIRECTIVE' ; ; XEQU - EXECUTE EQU ; XEQU LDY #0 LDA (OUTBUFF),Y ; GET 1ST OUTPUT CHAR BEQ _EERR ; IF NO LABEL - ERROR ; INY ; MOVE LABEL ADDRESS LDA (OUTBUFF),Y ; X STA SRCADR ; X INY ; X LDA (OUTBUFF),Y ; X STA SRCADR+1 ; X ; JSR XEXP ; EVALULATE EXPRESSION LDY #0 ; SET VALUE IN LABEL ENTRY STA (SRCADR),Y ; X TXA ; X INY ; X STA (SRCADR),Y ; X ; INY ; SET RESOLVE BYTE LDA RESBYT ; X AND #$3F ;AND OUT PASS 1&2 BITS ORA (SRCADR),Y ;OR WITH DEFINE BYTE IN LABEL TABLE ORA #EQULBL ;SET EQUATE TYPE STA (SRCADR),Y ; X ; ; SPECIAL CASE PRINT OUT ; _SPPRT JSR TSTLIST ; DO WE LIST BNE _EDONE ; IF NOT BR JSR TSTEJT ; TEST FPR PAGING ; LDA #0 ;INIT OUTPUT INDEX STA POX ;X ; LDA FR0 ; PRINT VALUE LDY FR0+1 ; X JSR PRHEX2 ;PRINT # JSR ALIST1 ;DO LISTING PLA ; REMOVE RETURN ADDR FROM STACK PLA ; X CLC _EDONE RTS ; ; ; _EERR LDA #EREQU JSR ERROR RTS .PAGE 'EXECUTE OPTION DIRECTIVE' ; ; XOPT - OPTION DIRECTIVE ; XOPT JSR GETCODE ; GET TOKEN CMP #CNO ; IS IT NO CODE BEQ OFF ; IF YES, TURNS OFF OPRION ; CMP #COBJ ; IF OPT NOT = OBJECT BNE _ON ; CONTINUE PHA ; ELSE SAVE CODE LDA LOCCNT ; SET CURRENT PC IN STA FR0 ; FR0 FOR ORG LDA LOCCNT+1 ; PROCESSING STA FR0+1 ; X JSR DOORG ; HANDLE AS ORG PLA ; GET CODE _ON TAY ; ELSE TURN ON OPTION LDA OPTTAB-COBJ,Y EOR #$FF AND OPTFLG STA OPTFLG JMP _OPT ; OFF ; TURN OFF OPTION JSR GETCODE ; GET NEXT TOKEN CMP #COBJ ; IF CODE NOT=OBJECT BNE _OFF1 ; CONTINUE PHA ; ELSE SAVE CODE JSR PORG ; PROCESS THE PREVIOUS ORG PLA ; GET CODE _OFF1 TAY ; LDA OPTTAB-COBJ,Y ; GET OPTION FLAG ORA OPTFLG ; OR WITH OTHER OPTIONS STA OPTFLG ; SAVE ; _OPT JSR GETCODE ; GET NEXT CODE CMP #CEOL ; ARE WE DONE? BNE XOPT ; IF NOT, DO NEXT OPTION LDA #0 ; GET # OF BYTES OF OBJECT STA ERRDEX ; ZERO ERROR INDEX INCASE THIS IS ERR ON RTS ; ; ; ; ; INDICATES OFF FOR EACH OPTION ; ; OPTTAB ; OPTTAB .BYTE OOBJ ; OBJECT .BYTE OERR ; ERROR .BYTE OPAGE ;PAGE .BYTE OLIST ; LIST .PAGE 'PROCESS IMPLIED INSTRUCTION' ; ; AXIMP - IMPLIED INSTRUCTION ; AXIMP JSR GETC1 ; GET OP CODE JSR OBJMAN ; PUT IN OBJECT BUFFER LDA #ONEBYT ; GET 1 BYTE OBJECT RTS .PAGE 'PROCESS RELATIVE BRANCH' ; ; AXREL - RELATIVE BRANCH ; AXREL JSR GETC1 ; PUT OP CODE IN OBJ BUFFER JSR OBJMAN ; X ; JSR XEXP ; EVAL EXPRESSION IN A & X SEC ; GET RELATIVE ADDR SBC LOCCNT ; (EXP-LOCCNT-2) TAY ; X TXA ; X SBC LOCCNT+1 ; X TAX ; X TYA ; X SEC ; X SBC #2 ; X JSR OBJMAN ; X TAY ; SAVE LOW ORDER BYTE TXA ; X SBC #0 ; X BNE _BACK ; THIS IS BR. BACK TYA ; IS BR FORWARD VALUE <80? BMI _VERR ; IF NOT ERROR BPL _VALOK ; ELSE OK ; _BACK TAX ; HIGH BYTE SHOULD BE FF INX ; X BNE _VERR TYA BMI _VALOK ; IF YES, OK ; ; _VERR JSR VERROR ; GO DO ERROR PROCESSING _VALOK LDA #TWOBYT ; TWO BYTES OF OBJECT RTS .PAGE 'PROCESS MISC INSTRUCTIONS' ; ; AXMISC - MISCELLANEOUS INSTRUCTIONS ; (JSR & JMP) ; ; AXMISC JSR GETC1 ; GET OP CODE TAX ; SAVE IT JSR GETCODE ; GET NEXT TOKEN CMP #CLPRN ; IS THIS INDIRECT JUMP BNE _JSR ; IF NOT, WE HAVE CORRECT OP ; LDX #$6C ; GET OP FOR INDIRECT JUMP BNE _IJMP _JSR DEC COX ; BACK UP TO START OF EXP _IJMP TXA ; GET OP CODE JSR OBJMAN ; PUT OP CODE IN OBJECT BUFFER JSR XEXP ; GET VALUE OF EXP JSR OBJM2 ; PUT BOTH BYTES TO BUFFER ; LDA #THRBYTE ; SET 3 BYTES OF OBJECT RTS .PAGE 'PROCESS MULTI ADDRESS INSTRUCTIONS' ; ; AXMULTI - MULTI-ADDRESS INSTRUCTION ; AXMULTI JSR GETCODE ; GET OP CODE INDEX ; ASLA ; GET VALID ADDR TYPE FOR THIS OP TAY LDA OPATYP-CSMULT-CSMULT,Y ; GET VALID ADDR TYPE 1 STA ZT1 ; SAVE LDA OPATYP-CSMULT-CSMULT+1,Y ; GET VALID ADDR TYPE 2 STA ZT2 ; SAVE ; JSR GETCODE ; GET TRIAL OP CODE STA STOP ; SAVE TRIAL OP JSR GETCODE ;GET NEXT TOKEN AND #$7F ;AND OUT MSB CMP #THEX2 ;IS THIS A # CODE ? BEQ _GEXP1 ;BR IF YES CMP #TACU ; IS THIS ACCUM BNE _GEXP ; IF NOT, IT'S # OR ( BEQ _AXM4 _GEXP1 DEC COX _GEXP JSR XEXP ; EVALUATE EXP JSR GETCODE ;GET TRIAL ADDR TYPE PHA ;SAVE IT LDA RESBYT ;GET RESOLVED BIT LSRA ;IS ABS ADR FLAG SET BCS _AXM5 ;IF YES; CAN'T BE ZERO PAGE ; ; TEST FOR POSSIBLE ZERO PAGE ; TXA ; TEST HIGH ORDER BYTE BNE _AXM5 ; IF NOT ZERO PAGE, BR ; PLA CMP #TABS ;IF TYPE IS NOT ABSOLUTE, BR BCC _AXM4 ; X SEC ; CHANGE ADDR TYPE SBC #3 ; X BNE _AXM4 ; UNCONDITIONAL BR ; _AXM5 PLA ; GET ADDR TYPE PHA CMP #TACU ; = IMM, INDY, INDX ? BCS _AXM1 ;IF NOT, THEN OKAY CMP #TIMM ; IF = IMM BNE _AXM6 ; JSR BIT8 ; TEST FOR 8 BIT VALUE JMP _AXM1 _AXM6 JSR _ADRR ; ELSE ERROR .PAGE ; ; ; ; TEST FOR VALID ADDRESS MATCH ; _AXM1 PLA _AXM4 ASLA TAY _AXM2 LDA ADRBIT,Y ; IF FIND BIT MATCH AND ZT1 BNE _VALID ; X LDA ADRBIT+1,Y ; X AND ZT2 BNE _VALID ; X ; ; ELSE TEST FOR NOT ZERO PAGE ; CPY #TZPGY*2 ;TYPE = ZPGY? BNE _ADRER ; IF NOT, THEN ERROR LDY #TABSY*2 ;CHANGE TO ABSY BNE _AXM2 ; TRY AGAIN ; _VALID TYA LSRA ; RESTORE INDEX OF 1 BYTE TABLE TAY PHA ; SAVE INDEX ; LDA MODBYT,Y ; GET MODIFIER PHA ; ; TEST FOR SPECIAL CASE ; LDA STOP ; GET TRIAL OP LSRA ; IS IT EVEN? BCS _SPEND ; IF NOT, NOT SPECIAL CASE ; ; HANDLE SPECIAL CASES ; CPY #TIMM ; IS THIS IMM ADDR TYPE? BNE _SP1 ; IF NOT, TRY NEXT SPECIAL ; PLA ; CHANGE MODIFIER BYTE LDA #0 ; (FOR LDX, STX, IMM) PHA BEQ _SPEND ; _SP1 CPY #TABSY ; IS THIS ABSOLUTE Y? BNE _SPEND ; IF NOT, NOT SPECIAL ; PLA ; CHANGE MODIFIER BYTE LDA #$1C ; (FOR CPY, ABSY) PHA ; X _SPEND PLA ; GET MODIFIER BYTE ORA STOP ; OR WITH TRIAL OP JSR OBJMAN ; PUT IN OBJECT ; LDA FR0 ; PUT VALUE IN OBJECT LDX FR0+1 ; X JSR OBJM2 ; X ; PLA ; GET INDEX TAY LDA LENTAB,Y ; GET LENGTH BY INSTRUCTION TYPE STA OBJDEX ; SET AS OBJECT INDEX RTS ;; _ADRER LDA MODEFLG ; IF MINI ASM CMP #MAMODE ; DON'T PUT OUT OBJ BEQ _ADRR LDA #0 ; PUT OUT 3 BYTES OF 0 TAX JSR OBJM2 JSR OBJMAN _ADRR LDA #ERADR ; PUT OUT ERROR _ADR1 JMP ERROR .PAGE ; ; EQUS FOR ADDR TYPE BITS ; IMM = $01 ABS = $02 ZPG = $04 ACU = $08 INDX = $10 INDY = $20 ZPGX = $40 ABSX = $80 ABSY = $01 ZPGY = $02 .PAGE ; ; OPATYP - VALID ADDRESS TYPES BY OP CODE ; ; STENUM - INDEX TO ADDR TYPE BYTE ; TYPEN = IMM+ZPG+ZPGX+ABS+ABSX+INDX+INDY TYPEN2 = ACU+ZPG+ZPGX+ABS+ABSX OPATYP .BYTE ABSY ; ORA .BYTE TYPEN ; .BYTE ABSY ; AND .BYTE TYPEN ; .BYTE ABSY ; EOR .BYTE TYPEN ; .BYTE ABSY ; ADC .BYTE TYPEN ; .BYTE ABSY ; STA .BYTE TYPEN-(.LOW.IMM) ; .BYTE ABSY ; LDA .BYTE TYPEN ; .BYTE ABSY ; CMP .BYTE TYPEN ; .BYTE ABSY ; SBC .BYTE TYPEN ; .BYTE 0 ; ASL .BYTE TYPEN2 ; .BYTE 0 ; ROL .BYTE TYPEN2 ; .BYTE 0 ; LSR .BYTE TYPEN2 ; .BYTE 0 ; ROR .BYTE TYPEN2 ; .BYTE 0 ; DEC .BYTE ZPG+ZPGX+ABS+ABSX ; .BYTE 0 ; INC .BYTE ZPG+ZPGX+ABS+ABSX ; .BYTE ZPGY+ABSY ; LDX .BYTE IMM+ZPG+ABS ; .BYTE 0 ; LDY .BYTE IMM+ZPG+ZPGX+ABS+ABSX ; .BYTE ZPGY ; STX .BYTE ZPG+ABS ; .BYTE 0 ; STY .BYTE ZPG+ZPGX+ABS ; .BYTE 0 ; CPX .BYTE IMM+ZPG+ABS ; .BYTE 0 ; CPY .BYTE IMM+ZPG+ABS ; .BYTE 0 ; BIT .BYTE ZPG+ABS .PAGE ; ; ADRBIT - VALID ADDRESS INDICATOR BY ADDRESS TYPE ; ; ONE BIT SET IN EACH ENTRY TO INDICATE ADDRESS TYPE ; ADRBIT .BYTE 00,INDX ; INDIRECT X .BYTE 00,INDY ; INDIRECT Y .BYTE 00,IMM ; IMMEDIATE .BYTE 00,ACU ; ACCUMULATOR .BYTE 00,ZPG ; ZERO PAGE .BYTE ZPGY,00 ; ZERO PAGE ] .BYTE 00,ZPGX ; ZERO PAGE X .BYTE 00,ABS ; ABSOLUTE .BYTE ABSY,0 ; ABSOLUTE Y .BYTE 00,ABSX ; ABSOLUTE X .PAGE ; ; MODBIT - MODIFIER BYTE FOR OPCODE BY ADDR TYPE ; MODBYT .BYTE $00 ; INDIRECT X .BYTE $10 ; INDIRECT Y .BYTE $08 ; IMMEDIATE .BYTE $08 ; ACCUMULATOR .BYTE $04 ; ZERO PAGE .BYTE $14 ; ZERO PAGE Y .BYTE $14 ; ZERO PAGE X .BYTE $0C ; ABSOLUTE .BYTE $18 ; ABSOLUTE Y .BYTE $1C ; ABSOLUTE X ; ; ; ; ; LENTAB - LENGTH OF INSTRUCTION BY ADDR TYPE ; LENTAB .BYTE 2 ; INDIRECT X .BYTE 2 ; INDIRECT Y .BYTE 2 ; IMMEDIATE .BYTE 1 ; ACCUMULATOR .BYTE 2 ; ZERO PAGE .BYTE 2 ; ZERO PAGE Y .BYTE 2 ; ZERO PAGE X .BYTE 3 ; ABSOLUTE .BYTE 3 ; ABSOLUTE Y .BYTE 3 ; ABSOLUTE X .PAGE ; ; AINIT - ASM INIT COMMON TO BOTH MINI & ASM ; ; AINIT2 - INIT FOR ASM PASS 2 ONLY ; AINIT ; ; SET DEFAULT PARMS ; ; JSR ARES2 ;CONTRACT TABLES LDX #SMBLD ; EXPAND SYMBOL TABLE DUMMYS LDY #4 ; X JSR EXPLOW ; X LDY #3 ; SET END OF SYMBOLS LDA #0 ; X STA (SMBLTP),Y ; X ; STA LISTDTD ; SET LIST DEVICE TO SCREEN STA ENTDTD ; SET ENTRY DEVICE TO MEMORY STA OBJDTD ; SET OBJECT DEVICE TO MEMORY AINIT2 ; ; INIT - TITLE & PAGE BUFFER ; ; LDX #TITLEND ;EXPAND TITLE BUFFER LDY #2 ; BY 2 BYTES JSR EXPLOW ; X ; LDX #PAGEND ;EXPAND PAGE BUFFER LDY #2 ; BY 1 BYTE JSR EXPLOW ; X ; LDY #0 ; SET LOCATION COUNTER =0 STY LOCCNT ; X STY LOCCNT+1 ; X STY EOFFLG ; SET NOT END OF FILE STY OPTFLG ; ZERO OPTION FLAG STY LNCNT ; # LINES ON PAGE = 0 STY COPTR ; SET CURRENT ORG PTR TO = 0 STY COPTR+1 ; X STY ERRDEX ; CLEAR ERROR INDEX STY ERRCNT ; AND COUNT OF ERRORS ; LDA #1 ; GET # BBYTES IN TITLE & PAGE STA (TITLEP),Y ; SET BLANK TITLE STA (PAGEP),Y ; SET BLANK PAGE INY ; X LDA #$20+$80 STA (TITLEP),Y ; X STA (PAGEP),Y ; X ; ; SET DEFAULT TABS ; LDA #12+PLST STA TAB1 LDA #17+PLST STA TAB2 LDA #27+PLST STA TAB3 ; ; INIT CURRENT STMT POINTER ; LDA TXTTAB STA STMCUR LDA TXTTAB+1 STA STMCUR+1 RTS .PAGE ; ; ARESET - RESET AFTER ASM ; ARES1 LDA #EMODE ; SET TO EDITOR MODE STA MODEFLG ARESET LDA #0 ; RESET STA ENTDTD ; ENTRY DEVICE STA LISTDTD ; LIST DEVICE STA AUTOFLG ; AUTO FLAG STA ERRDEX ; RESET ERROR INDEX ; ARES2 LDX #SMBLTP+2 ;POINT TO START OF CONTRACT LDA TXTEND ; CONTRACT TABLES LDY TXTEND+1 ; X JMP CLR1 ; X .PAGE ; ; XEXP - EXECUTE EXPRESSION ; ; ON EXIT FR0 - VALUE ; RESBYT - MINUS IF VALUE UNRESOLVED ; XEXP LDA #0 ; ZERO RESOLVED BYTE STA RESBYT ; X ; JSR MOVNUM ; MOVE # FROM OUTPUT STX FR0 ; SAVE # STA FR0+1 ; _XEXP1 JSR GETCODE ; GET OPERATOR CMP #TEOE ; IS IT END OF EXPRESSION? BEQ _EXDONE ; IF YES, DONE PHA ; SAVE OPERATOR JSR MOVNUM ; GET OPERAND STX FR1 ; SAVE OPERAND STA FR1+1 ; PLA ; GET SAVED OPERATOR JSR __EDUM ; GO TO PROPER ROUTINE ; ; RETURN HERE FROM OPERATOR ; JMP _XEXP1 ; IF OPERATION OK ..DO NEXT ; ; ; ; ; ; _EXDONE LDA FR0 ;GET RESULTS LDX FR0+1 ; RTS .PAGE ; ; GO TO PROPER ROUTINE ; __EDUM ASLA TAY LDA TABEXP-CPLUS-CPLUS+1,Y PHA LDA TABEXP-CPLUS-CPLUS,Y PHA RTS ; ; ; ; ; ROUTINE ADDRESSES FOR EXECUTE EXPRESSION ; TABEXP .WORD ADD-1 ; + .WORD SUB-1 ; - .WORD MUL-1 ; * .WORD DIV-1 ; / .WORD AND-1 ; & .PAGE ; ; INTEGER ADD ; AND LDA FR0 AND FR1 STA FR0 LDA FR0+1 AND FR1+1 STA FR0+1 RTS ; ; ; ; INTEGER ADD ; ADD CLC LDA FR0 ADC FR1 STA FR0 LDA FR0+1 ADC FR1+1 STA FR0+1 RTS ; ; INTEGER SUBTRACT ; SUB SEC LDA FR0 SBC FR1 STA FR0 LDA FR0+1 SBC FR1+1 STA FR0+1 RTS ; ; DIV -- DIVIDE, FR0 BY FR1 ; ; ENTER: 16-BIT DIVIDEND IN FR0 ; 16-BIT DIVISOR IN FR1 ; ; EXIT: 16-BIT QUIOTIENT IN FR0 ; DIV JSR _MDSU ; SET UP ; _DOLP ASL FR0 ROL FR0+1 ROL FR0EX ROL FR0EX+1 ; SHIFT DIVIDEND LEFT ; SEC LDA FR0EX SBC FR1 ; TRIAL SUBTRACT OF LSB TAX ; (SAVE RESULT) LDA FR0EX+1 SBC FR1+1 ; ...& MSB BCC _DVJN ; TRIAL SUBTRACT DIDN'T WORK ; STA FR0EX+1 STX FR0EX ; SUBTRACT WORKED...UPDATE DIV'D INC FR0 ; ...& QUIOTIENT ; _DVJN DEY BNE _DOLP ; LOOP TILL DONE RTS ; ; ; ; MUL -- MULTIPLY ; ; ENTER: 16 BIT ARGUMENTS IN FR0 & FR1 ; ; EXIT: PRODUCT IN FR0 ; ; MUL JSR _MDSU ; _MOLP ; OUTER LOOP LSR FR0EX+1 ROR FR0EX ROR FR0+1 ROR FR0 ; SHIFT PARTIAL PROD & MULT'R DEY BMI _MDRT ; DONE WITH 17 SHIFTS 16 ADDS ; BCC _MOLP ; LS BIT WAS 0 NO ADD LOOP ; CLC ; LS BIT WAS 1 DO ADD LDX #-2 ; CUTE TRICK _MILP LDA FR1+2,X ; +2 BECUZ X STARTS OFF AT -2 ADC FR0EX+2,X ; STA FR0EX+2,X ; ADD TO PARTIAL PRODUCT INX BNE _MILP ; LOOPS ONLY TWICE BEQ _MOLP ; TO NEXT BIT ; ; ; MULTIPLY/DIVIDE SETUP ; ; _MDSU LDA #0 STA FR0EX STA FR0EX+1 ; 0 TO EXTENSION LDY #16 ; LOOP COUNTER _MDRT RTS .PAGE ; ; MOVNUM - MOVE # TO FR0 FROM OUTPUT BUFFER ; ; ON EXIT: X - LOW ORDER BYTE ; A - MSB ; ; SET RESOLVE BYTE MOVNUM JSR ORRES ; OR # CODE WITH RESOLVE BYTE JSR GETCODE TAX JSR GETCODE RTS ; ; ; ; ; ; ORRES - OR # CODE WITH RESOLVE BYTE ; ORRES LDX #0 ;GET RESOLVED CODE JSR GETCODE BPL _RES ;IF CODE = 1 THEN, VALUE RESOLVED LDX #1 ;ELSE GET UNRESOLVED CODE _RES TXA ;PUT IT IN A ORA RESBYT STA RESBYT RTS .PAGE ; ; BIT8 - TEST FOR VALID 8 BIT VALUE IN FR0 ; ; BIT8 LDA FR0+1 ; GET HI ORDER BYTE BEQ _OKB ; IF = 0, THEN VALUE OK ; CMP #$FF ; TEST FOR MINUS 8 BIT VALUE BEQ _OKB ; _ERRB JSR VERROR ; PROCESS ERR _OKB ; GET VALUE LDA FR0 RTS .PAGE ; ; OBJMAN - OBJECT MANGER ; ; ; OBJM2 - PUT 2 BYTES TO OBJECT BUFFER ; ; ON ENTRY A - 1ST BYTE ; X - 2ND BYTE ; OBJM2 JSR OBJMAN ; PUT 1ST BYTE TXA ; GET SECOND BYTE ; ; FALL THROUGH TO OBJMAN ; ; OBJMAN LDY OBJDEX STA (OBJBUFF),Y INC OBJDEX RTS .PAGE ; ; ABORT ; ABORT PLA LDA #ERNORG ; GET NOORG ERROR MESSAGE JSR ERROR ; PRINT ERROR JSR PRTERR JMP ABRK ; ABORT .PAGE ; ; OCNTL - OUTPUT CONTROLLER (OBJRCT & LISTING) ; OCNTL LDA PASSFLG ; GET PASS FLAG BPL _OC2 ; IF PASS = 2 THEN DO OUTPUT _OC1 CLC ; INCR LOC COUNTER LDA LOCCNT ADC OBJDEX STA LOCCNT LDA LOCCNT+1 ADC #0 STA LOCCNT+1 RTS _OC2 LDA OPTFLG ; GET OPTION FLAG AND #OOBJ ; IF OBJ OPT = NO, THEN BR BNE _OC5 ; ; PUT OBJECT TO MEMORY OR FILE ; LDA OBJDEX ; GET OBJECT INDEX BEQ _OC5 ; IF NONE, BR LDA LOCCNT ; SAVE LOCATION COUNTER PHA ; X ORA LOCCNT+1 ; IF LOC =0 BEQ ABORT ; ABORT ASM LDA LOCCNT+1 ; X PHA ; LDY #0 STY TOBJDEX ; SET OBJECT INDEX COUNTER _OC3 LDA (OBJBUFF),Y ; GET OBJECT BYTE LDX OBJDTD ; GET OBJECT DEVICE BNE _OC6 ; IF = FILE, BR ; LDY #0 ; ELSE PUT TO MEMORY STA (LOCCNT),Y ; X JMP _OC7 ; ; _OC6 JSR PUTC1 ; PUT TO FILE ; _OC7 INC LOCCNT BNE _OC4 INC LOCCNT+1 _OC4 INC TOBJDEX LDY TOBJDEX CPY OBJDEX BNE _OC3 ; PLA ; RESTORE LOCATION COUNTER STA LOCCNT+1 ;X PLA ; X STA LOCCNT ; ? .PAGE _OC5 ; ; PRINT LISTING ; ALIST LDA #0 ; INIT OBJECT BUFFER PTR STA TOBJDEX ; X STA POX ; INIT OUTPUT INDEX ; JSR TSTLIST ; DO WE LIST? BNE _OC1 ; DO WE LIST? _AL6 ; JSR POBJL ; ELSE PRINT OBJECT LINE ; ALIST1 _AL1 LDA MODEFLG ; GET MODE CMP #MAMODE ; = MINI ASM BEQ _AL2 ; IF YES, DO CR ; JSR PIN ; PRINT INPUT LINE JMP _AL4 ; _AL2 JSR PRCR ; PRINT RETURN _AL4 LDA OBJDEX ; GET OBJECT INDEX BEQ _AL3 ; IF =0 NONE TO PRINT JSR POBJL ; ELSE PRINT OBJECT LINE JMP _AL2 ; REPEAT _AL3 TSTOERR LDA OPTFLG ; GET OPTION FLAG AND #OERR ; IS ERROR, OPTION = NO BNE _AL5 ; IS SO, SKIP ERROR LISTING JSR PRTERR ; PRINT ERRORS _AL5 RTS .PAGE ; ; POBJL - PRINT 1 LINE OF OBJECT ; POBJL ; JSR TSTEJT LDY LOCCNT+1 LDA LOCCNT ; P.C. GETS PRINTED JSR PRADRB ; X LDA OBJDEX ; GET OBJECT INDEX BEQ _PODONE ; X=0 NONE TO PRINT LDA OLBCNT ; GET # OF BYTES TO PRINT ON LINE STA ZT1 ; SAVE AS COUNTER ; _PO1 LDY TOBJDEX ; GET PTR TO OBJECT BYTE LDA (OBJBUFF),Y ; GET OBJECT BYTE JSR PRIHEX ; PRINT AS HEX INC LOCCNT ; INCR LOCATION COUNTER FOR NEXT PRINT BNE _PO2 ; X INC LOCCNT+1 ; X _PO2 INC TOBJDEX ; POINT TO NEXT BYTE DEC OBJDEX ; DEC # BYTES LEFT TO IN BUFFER BEQ _PODONE ; IF =0 THEN DONE DEC ZT1 ; DEC # BYTES TO PRINT ON LINE BNE _PO1 ; IF NOT = 0 DO AGAIN _PODONE RTS .PAGE ; ; PIN - PRINT INPUT LINE TO ASM LISTING ; PIN LDA #0 ; INIT INPUT BUFFER PTR STA CIX ; X ; LDA #PLST ; GET DISP TO START OF INPUT LINE PRINT OUT JSR PRPAD ; PRINT BLANKS TO START OF INPUT ; ; PRINT LABEL ; LDA IDISPL ; DISPL TO END OF LABEL (ST OF INST) JSR PRPL ; PRINT PARTIAL LINE ; LDA TAB1 ; PRINT PADDING BLANKS JSR PRPAD ; X ; ; PRINT INSTRUCTION ; LDA ADISPL ; DISPL TO END OF INST (ST OF ADR) JSR PRPL ; PRINT PARTIAL LINE LDA TAB2 ; PRINT PADDLING BLANKS JSR PRPAD ; X ; ; PRINT ADDRESS ; LDA CDISPL ; PRINT ADDR JSR PRPL ; X LDA TAB3 ; PRINT PADS JSR PRPAD ; ; PRINT COMMENT ; _PIN1 JSR GETIN ; GET CHAR FROM INBUFF PHA ; SAVE IT JSR PRCHAR ; PRINT IT PLA ; GET IT AGAIN CMP #CR ; IS IT CARRIDGE RETURN? BNE _PIN1 ; IF NOT REPEAT ; RTS .PAGE ; ; PRPL - PRINT PARTIAL LINE FOR ASM ; ; ON ENTRY A - DISPL TO LAST CHAR TO PRINT +1 ; CIX - DISPL OF 1ST CHAR TO PRINT ; PRPL SEC ; GET # OF BYTES TO PRINT SBC CIX ; X STA PRCNT ; SAVE IT AS COUNTER BEQ _PRPL2 BCC _PRPL2 ; _PRPL1 JSR GETIN ; GET A CHAR JSR PRCHAR ; PRINT IT DEC PRCNT ; DEC COUNTER BNE _PRPL1 _PRPL2 RTS .PAGE ; ; PRPAD - PRINT PADDING BLANKS FROM ; POX TO TAB VALUE ; ; ON ENTRY A - TAB VALUE ; POX - CURRENT OUTPUT CHAR COUNT ; PRPAD SEC SBC POX ; GET # OF BLANKS TO PRINT BCC _PAD ; IF TAB <= CURRENT INDEX, BR BEQ _PAD BNE PRBLANKS ; PRINT BLANKS .PAGE ; ; PRBLANKS - PRINT BLANKS ; ; ON ENTRY A - # OF BLANKS TO PRINT ; ; PRBLK3 - PRINT 3 BLANKS ; ; ; ; PRBLK3 LDA #3 ; GET 3 BLANKS TO PRINT PRBLANKS STA BLKCNT ; SAVE # OF BLANKS TO PRINT _PRB JSR PRBLK1 ; PRINT A BLANK DEC BLKCNT BNE _PRB _PAD RTS .PAGE ; ; TSTLIST - TEST TO SEE IF LINE NEEDS LISTING ; ; ON EXIT CC = Z IF LIST ; CC = NZ IF NO LIST ; ; TSTLIST LDA PASSFLG ; GET PASS FLAG BMI _TL1 ; IF PASS1, DON'T LIST ; LDA OPTFLG ; GET OPTION FLAG AND #OLIST ; IF LIST = YES BEQ _TL1 ; THIN LIST (ALREADY SET) LDA OPTFLG ; ELSE GET OPTION FLAG AGAIN AND #OERR ; IF ERROR = NO BNE _TL1 ; DON'T LIST (ALREADY SET) LDA ERRDEX ; ELSE IF NO ERRORS BEQ _NL ; THIN DON'T LIST LDA #0 ; ELSE SET CC FOR LIST _TL1 RTS ; _NL LDA #$FF RTS .PAGE ; ; TSTEJT - TEST FOR PAGE EJECT ; TSTEJT LDA LNCNT CMP LINESPERPAGE BNE _TSTE1 ; IF NOT, DONE ; LDA OPTFLG ; GET OPTION FLAG AND #OPAGE ; IS PAGE OPTION = NO? BNE _TSTE1 ; IF SO, DON'T DO PAGE EJECT ; LDA POX ; SAVE OUTPUT INDEX PHA JSR PAGE1 ; DO PAGE EJECT PLA STA POX ; RESTORE INDEX _TSTE1 INC LNCNT ; INCR # LINES ON PAGE RTS .PAGE 'AUTO' ; ; AUTO - PUT OUT AUTO LINE NUMBER ; AUTO LDA CURLN ; MOVE CUR LINE # STA TSLNUM ; TO SEARCH LINE # STA FR0 ; & FR0 FOR CONVERT LDA CURLN+1 ; X STA TSLNUM+1 ; X STA FR0+1 ; X ; JSR GETSTMT ; DOES STMT ALREADY EXISTS? BCS _AUTO ; IF NOT, DO AUTO LDA #AUTOFF ; TURN OFF AUTP STA AUTOFLG ; X JMP ESYNTAX ; _AUTO JSR PRINUM ; PRINT THE # ; LDY TPCIX ; POINT TO LAST DIGIT OF NUM LDA (INBUFF),Y ; GET IT AND #$7F ; TURN OFF MSB STA (INBUFF),Y ; SAVE IT INY ; POINT TO NEXT SPACE LDA #$20 ; GET BLANCK STA (INBUFF),Y ; PUT IN INPUT LINE INY ; POINT TO FREE SPACE STY TPCIX ; SAVE ; JSR PRCHAR ; PRINT THE BLANK ; ; SET UP FOR I/O ; CLC ; GET INPUT BUFFER ADDR LDA INBUFF ; X ADC TPCIX ; X (LINE # LENGTH) STA INBUFF ; X LDA INBUFF+1 ; X ADC #0 ; X STA INBUFF+1 ; X ; LDA #127 ; GET INPUT BUFFER LENGTH SEC ; X SBC TPCIX ; X (LINE # LENGTH) TAY ; JSR GCXI ;SET DEVICE & COMMAND ; JSR IO3 ; DO I/O JSR IOTEST ; TEST RESULT JMP INTLBF ; RE-INIT INBUFF ; ; ; ; ; UPCUR - UPDATE CURRENT LINE # FOR AUTO OR REN ; UPCUR UPAUTO CLC ; NEW CURRENT LINE NUMBER EQU LDA CURLN ; CUR LINE NUM+INCR ADC LNINCR ; X STA CURLN ; X LDA CURLN+1 ; X ADC LNINCR+1 ; X STA CURLN+1 ; X BCC _TSTE1 ; JUST AN 'RTS' IN <= 65535 ; _UPERR LDA #EROVFL JSR ERROR .PAGE 'I/O ROUTINE'S' ; LOCAL ; ; GETLINE - GET A LINE OF INPUT FOR SOMEONE ; ; ; GLINE - GET LINE (PROMPT ONLY) ; GNLINE - GET NEW LINE (CR, PROMPT) ; GNLINE LDA AUTOFLG ; GET AUTO FLAG BNE AUTO ; IF IN AUTO, GO DO IT ; GLGO JSR GCXI ; GET COMMAND & DEVICE JSR IO1 ; GO DO I/O JMP IOTEST ; GO TEST RESULT .PAGE ; ; PRINT CR ; PRCR LDA #CR ; FALL THRU TO PUT THE CHAR ; ; ; PUTCHAR - PUT ONE CHAR TO LIST DEVICE ; PRCHAR PUTCHAR LDX LISTDTD ; GET LIST DEVICE PUTC1 PRCX INC POX ; INCR OUTPUT INDEX PHA ; SAVE IO BYTE JSR GLPX ; SET DEVICE ; LDA ICAUX1,X ; SET UP ZERO PAGE IOCB STA ICAUX1-IOCB+ZICB LDA ICAUX2,X STA ICAUX2-IOCB+ZICB ; PLA TAY JSR _PDUM ; ; RETURN HERE FROM ROUTINE ; TYA ; TEST STATUS JMP IOTES2 ; ; _PDUM LDA ICPUT+1,X ; GO TO PUT ROUTINE PHA LDA ICPUT,X PHA TYA LDY #$92 ; LOAD VALUE FOR CIO ROUTINE RTS ; ; GCXI LDX ENTDTD ; GET DEVICE LDA #ICGTR ; GET COMMAND ; GLPCX STA IOCMD GLPCX1 GLPX STX IODVC ; AS I/O DEVICE JMP LDDVX ; LOAD DEVICE X .PAGE ; ; HPUTO2 -- CONDITIONAL PUTO2, HEADER BYTES ONLY ; HPUTO2 LDY OBJDV*16+ICDNO ; GET DEVICE # CPY #9 ; DEVICE 9? BNE PUTO2 ; NO RTS ; YES...DON'T DO IT! ; ; ; PUTO2 - OUTPUT 2 BYTES TO OBJECT FILE ; ; ; ON ENTRY A - OBJECT BYTE HIGH ; X - OBJECT BYTE LOW ; ; ; PUTOBJ ; ; ON ENTRY A - OBJECT BYTE ; PUTO2 PHA TXA JSR PUTOBJ ; PLA PUTOBJ LDX OBJDTD BNE PUTC1 RTS ; IN CASE .PAGE ; ; OPEN - OPEN FILE ; ON ENTRY A - TYPE OF RECORD ; ; ; FLIST - OPEN FOR LIST ; ; FLOAD - OPEN FOR LOAD ; FLIST LDA #8 ; CODE FOR OUTPUT LDY #LISDV ; USE LIST DEVICE STY LISTDTD ; SET LIST DEVICE JMP OPEN ; OPEN DEVICE ; ; ; FLOAD2 INC COX FLOAD LDA #4 ; CODE FOR INPUT LDY #LOADDV ; USE LOAD DEVICE STY ENTDTD JMP OPEN ; OPEN DEVICE ; ; ; FOBJ LDA #8 ; CODE FOR OUTPUT LDY #OBJDV ; USE OBJECT DEVICE STY OBJDTD ; SET OBJECT DEVICE ; ; OPEN PHA ; SAVE TYPE RECORD STY IODVC ; SET DEVICE # JSR STRMOV ; MOVESS FNAM TO BUFFER PLA ; SECOND ENTRY POINT...FOR OBJECT FILES OP2 PHA JSR CLSYSD ; CLOSE THIS FILE JSR LDDVX LDA #ICOIO STA IOCMD ; "OPEN" COMMAND STA ICCOM,X LDA #.LOW.FNBUFF STA ICBAL,X LDA #.HIGH.FNBUFF STA ICBAH,X PLA STA ICAUX1,X LDA #0 LDY FNBUFF CPY #'C BNE OP2X LDY FNBUFF+1 CPY #'9 BNE OP2X LDA #$80 OP2X STA ICAUX2,X JSR CIO JMP IOTEST .PAGE ; ; LDDVX - LOAD X REG WITH I/O DEVICE OFFSET ; LDDVX LDA IODVC ; GET DEVICE ASLA ; MULT BY 16 ASLA ASLA ASLA TAX ; PUT INTO X RTS ; AND RETURN .PAGE ; ; IOTEST - TEST I/O STATUS ; IOTEST JSR LDIOSTA ; LOAD I/O STATUS IOTES2 BMI SICKIO ; BR IF BAD RTS ; ELSE RETURN ; SICKIO LDY #0 ; RESET DISPLAY FLAG LDY DSPFLG ; STA ERRNUM ; SAVE ERROR # ; CMP #ICSBRK ; IF BREAK THEN BNE _SIO1 ; SUMULATE ASYNC BR LDY #0 STY BRKBYT ; X JMP CLFILE ; GO CLEAN UP FILES _SIO1 ; LDA IODVC CMP ENTDTD ; WAS IT ENTER DEVICE BEQ _SIO2 ; IF YES BR BNE _SIO6 ; _SIO7 STA ERRNUM ; SAVE ERROR # JSR ARES1 ; RESET FOR EDITOR ; _SIO2 LDA MODEFLG BMI _SIO5 JSR CLFILE ; CLEAR UP FILES BNE _SIO2B ; IF NOT EOF, PRINT ERROR LDY MODEFLG ; IF NOT IN EDITOR BNE _SIO2A ; RETURN TO CALLER JMP ESYN2 ; ELSE GO TO SYNTAX ; _SIO6 JSR CLFILE BEQ _SIO2A ; DON'T PRINT MESSAGE, IF EOF _SIO2B JSR ERROR _SIO2A RTS ; ; _SIO5 LDA PASSFLG ; GET PASSFLAG BPL _SIO6 ; IF PASS 2, CLOSE DEVICE LDA ERRNUM CMP #$88 BNE _SIO6 LDX ENTDTD ; GET LOAD DEVICE LDA #PTCMD ; GET POINT COMMAND JSR GLPCX ; LDA #0 ; SET UP FOR POINT STA ICAUX5,X ; X LDA TEMPRL ; GET VALUE LOW FOR PRINT STA ICAUX3,X ; X LDA TEMPRL+1 ; GET VALUE HIGH FOR POINT STA ICAUX4,X ; X JSR IO7 ; DO POINT JSR LDIOSTA ; GET STATUS BMI _SIO7 ; IF ERROR HANDLE IT LDA #$88 RTS ; ; CLFILE LDA #SCRDV STA ENTDTD STA LISTDTD ; RESET LIST DEVICE STA OBJDTD ; RESET OBJECT DEVICE JSR CLSALL ; CLOSE ALL DEVICES LDA ERRNUM ; GET ERROR # CMP #$88 ; IF END OF FILE RTS .PAGE ; ; CLSYSD - CLOSE SYSTEM DEVICE ; CLSYSD JSR LDDVX ; LOAD DEVICE X REG BEQ NOCDO ; DON'T CLOSE DEVICE # 0 LDA #ICCLOSE ; LOAD CLOSE CORD JMP IO8 ; GO CLOSE ; ; ; LDIOSTA - LOAD I/O STATUS ; LDIOSTA JSR LDDVX ; GET DEVICE X REG LDA ICSTA,X ; GET STATUS NOCDO RTS ; RETURN ; ; ; ; ; CLSALL - CLOSE ALL DEVICES ; CLSALL LDY #3 ; START AT 3 CLALL7 STY IODVC CLALL1 JSR CLSYSD ; CLOSE DEVICE DEC IODVC ; DECR DEVICE # BNE CLALL1 ; BR IF NOT 0 RTS ; DONE IF 0 .PAGE ; ; I/O CALL ROUTINE ; IO1 LDY #119 ; BUFL = 119 BNE IO3 IO2 LDY #0 ; BUFL = 0 IO3 LDA #0 ; BUFL < 256 IO4 STA ICBLH,X ; SET BUFL TYA STA ICBLL,X IO5 LDA INBUFF+1 ; LOAD INBUFF VALUE LDY INBUFF IO6 STA ICBAH,X ; SE BUF ADR TYA STA ICBAL,X IO7 LDA IOCMD ; LOAD COMMAND IO8 STA ICCOM,X ; SET COMMAND LDA #0 ; CLEAR AUX 2 STA ICAUX2,X JMP CIO ; GO DO I/O .PAGE ; ; TSTBRK - TEST FOR BREAK ; ; ON EXIT CC = 0 IF NO BREAK ; CC = NOT 0 IF BREAK HIT ; TSTBRK LDY #0 ; LDA BRKBYT ; LOAD BREAK BYTE BNE _TB2 LDY #$FF ; TURN OFF BRK BYTE STY BRKBYT _TB2 TYA ; SET COND CODE RTS ; DONE .PAGE ; ; GETSTMT - GET STMT IN STMT TABLE ; SEARCH FOR STMT THAT WAS TSLNUM ; SET STMCUR TO POINT TO IT IF FOUND ; OR TO WHERE IT WOULD GO IF NOT FOUND ; CARRY SET IF NOT FOUND GETSTMT LDA TXTTAB+1 ; START AT TOP OF TABLE LDY TXTTAB ; STA STMCUR+1 ; SET STMCUR = TOP OF TABLE STY STMCUR ; ; _GS2 JSR TSTTEND ; TST FOR END OF TXT BCS _GSRT1 ; LDY #1 ; GET INDEX LDA (STMCUR),Y ; GET STMT LNO (HI) CMP TSLNUM+1 ; TEST WITH TSLNUM BCC _GS3 ; BR IF S<TS BNE _GSRT1 ; BR IF S>TS DEY ; EQUAL...TEST LOW BYTE LDA (STMCUR),Y CMP TSLNUM BCC _GS3 ; BR S<TS BNE _GSRT1 ; BR S>TS CLC ; S=TS, CLEAR CARRY _GSRT1 RTS ; AND RETURN (FOUND) ; _GS3 JSR GETLL ; GET TO NEXT LINE JSR GNXTL JMP _GS2 ; ; GETLL LDY #2 ;GET STATEMENT LENGTH LDA (STMCUR),Y RTS ; GNXTL CLC ;GET NEXT STATEMENT GNXTL1 ADC STMCUR STA STMCUR TAY LDA STMCUR+1 ADC #0 STA STMCUR+1 RTS .PAGE 'ERROR ROUTINE' ; ; ; ; ; ERROR - COMMON ERROR ROUTINE ; VERROR LDA #ERVAL ; VALUE ERROR EDERR ERROR LDX #0 ; RESET DISPLAY FLAG STX DSPFLG LDX ERRDEX ; GET INDEX INTO ERROR BUF CPX #3 ; IS BUFFER FULL? BCS _ERTN ; IF YES, DON'T STORE ERROR # DEX ;POINT TO LAST ERROR CMP ERRBUF,X ;IS IT SAME AS CURRENT ERROR ? BEQ _ERTN ;IF YES DON'T PUT IT IN BUFFER INX ;POINT TO NEXT ERROR LOCATION STA ERRBUF,X ; SAVE ERROR # INC ERRDEX ; INCR INDEX _ERTN ; ASLA ; CARRY WILL BE SET IF I/O ERROR LDA MODEFLG BPL _ERTN1 ; BR IF NOT ASM BCC _ASMERR ; BR IF NOT I/O ERROR _ERTN1 JSR PRTERR LDY MODEFLG ; GET MODE DEY ; ONLY DEBUG=(1) MODE WILL BE >=0 ; (MINI ASM CAN'T GIVE I/O ERROR BMI _EDERR JMP DSYNTAX _EDERR JMP ESYNTAX _PRNON _ASMERR RTS ; RETURN TO CALLER ; ; ; ; ; PRTERR - PRINT ERROR MESSAGE ; PRTERR LDA ERRDEX ; GET ERROR INDEX BEQ _PRNON ; IF NO ERRORS, EXIT LDA MODEFLG ; IF IN ASM MODE BPL _PRT1 ; X JSR TSTEJT ; TEST FOR PAGE EJECT INC ERRCNT ; ANOTHER ERROR BNE _PRT1 ; OK DEC ERRCNT ; OOPS...256 OR MORE _PRT1 LDA #BELL ; RING BELL JSR PRCHAR ; LDX #.LOW.ERRMSG ; GET MESSAGE ADDR LOW LDY #.HIGH.ERRMSG ; GET MESSAGE ADDR HIGH JSR MSGXY ; GO PRINT MESSAGE ; ; _PENUM DEC ERRDEX ; POINT TO NEXT ERROR # BMI _PEDONE ; IF NONE LEFT, DONE LDX ERRDEX ; GET ERROR INDEX LDA ERRBUF,X ; GET ERROR # JSR PRNUMA ;PRINT NUMBER IN A JSR PRBLK1 ; PRINT A BLANK JMP _PENUM ; _PEDONE LDX #0 ; ZERO ERROR INDEX STX ERRDEX ; X JMP PRCR ; PRINT RETURN ; ; ; ERRMSG .BYTE '***ERROR -',$80+' ' .PAGE 'PRINT ROUTINES' ; PRINT NUMBER IN A-REGISTER ; PRNUMA STA FR0 LDA #0 ; UPPER BYTE ASSUMED=0 STA FR0+1 ; FALL THRU TO PRINUM ; ; ; PRINUM - PRINT A DECIMAL NUMBER ; ; ON ENTRY FR0 - CONTAINS 2 BYTE NUMBER ; PRINUM JSR IASC ; MAKE PRINTBLE LDX INBUFF LDY INBUFF+1 JSR MSGXY ; PRINT IT STY TPCIX RTS ; ; ; ; ; IASC - CONVERT INTEGER TO ASCII ; ; ON ENTRY FR0 - CONTAINS INTEGER ; ON EXIT INBUFF - POINTS TO START OF # ; IASC JSR IFP ; CONVERT TO FP JMP FASC ; CONVERT TO ASCII .PAGE ; ; PRHEX2 - PRINT A 2 BYTE HEX NUMBER ; ; ON ENTRY A - 2ND BYTE TO PRINT (LOW) ; Y - 1ST BYTE TO PRINT (HIGH) ; PRHEX2 PHA ; SAVE 2ND BYTE TYA ; GET 1ST BYTE TO PRINT JSR PRIHEX ; GO PRINT IT ; PLA ; GET 2ND NUMBER ; ; ; ; ; PRIHEX - PRINT A 1 BYTE HEX NUMBER ; ; ON ENTRY A - HEX # ; PRIHEX PHA ; SAVE THE HEX # ; LSRA ; GET LEFT DIGIT LSRA LSRA LSRA ; JSR _PRIH ; GO PRINT IT ; PLA ; GET # AGAIN AND #$0F ; GET RIGHT DIGIT _PRIH ORA #'0 ; 0-9 OK CMP #'9+1 ; BUT...IF > '9'... BCC _PRIH2 ADC #6 ; ADJUST THUSLY _PRIH2 JMP PRCHAR ; PRINT IT ; ; ; ; ; ; ; ; PRADRB - PRINT ADDR FOLLOWED BY BLANK ; ; ON ENTRY A - ADDR LOW ; Y - ADDR HIGH ; PRADRB JSR PRHEX2 ; PRINT ADDR ; (FALL THRU) ; ; PRINT ONE BLANK ; PRBLK1 LDA #$20 JMP PRCHAR ; ; ; ; ; ; PRHEXB - PRINT HEX NUMBER FOLLOWED BY A BLANK ; ; ; ON ENTRY A - HEX # ; PRHEXB JSR PRIHEX JMP PRBLK1 ; ; ; .PAGE ; ; MSGXY - PRINT A MESSAGE ; ; ON ENTRY X - MESSAGE ADDR LOW ; Y - MESSAGE ADDRHIGH ; MESSAGE HAS MSB OF LAST BYTE ON ; ; (ASSUMES MESSAGES DO NOT CONTAIN CR OR NON-PRINTING CHAR) ; MSGXY STX MSGADR ; SAVE ADR STY MSGADR+1 ; X ; LDY #$FF ; INIT INDEX _MSG1 INY STY ZT1 ; INCR & STORE INDEX LDA (MSGADR),Y ; GET CHAR PHA ; SAVE CHAR AND #$7F ; TURN ON MSB ; JSR PRCHAR ; GO PRINT CHAR ; LDY ZT1 ; RETURN WITH THIS OR BUMP IT PLA ; GET CHAR AGAIN BPL _MSG1 ; IF NOT END OF MESSAGE - DO AGAIN RTS ; ; ; ; ; MSGXYCR - PRINT A CR AFTER MESSAGE ; MSGXYCR JSR MSGXY ; PRINT MESSAGE JMP PRCR ; PRINT CR .PAGE 'ATARI CARTRIDGE VECTORS' *=CRTGI SCVECT RTS .WORD COLDSTART .BYTE 0 ; CART EXISTS .BYTE 5 ; FLAG .WORD SCVECT ; COLDSTART ENTRY ADDR .PAGE 'END OF BASIC' .END